mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-10-27 14:40:29 +00:00
Support optional trailing positional arguments
This commit is contained in:
@@ -279,7 +279,7 @@ fn impl_from_args_struct(
|
||||
.collect();
|
||||
|
||||
ensure_unique_names(errors, &fields);
|
||||
ensure_only_last_positional_is_optional(errors, &fields);
|
||||
ensure_only_trailing_positionals_are_optional(errors, &fields);
|
||||
|
||||
let impl_span = Span::call_site();
|
||||
|
||||
@@ -441,17 +441,22 @@ fn get_help_triggers(type_attrs: &TypeAttrs) -> Vec<String> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Ensures that only the last positional arg is non-required.
|
||||
fn ensure_only_last_positional_is_optional(errors: &Errors, fields: &[StructField<'_>]) {
|
||||
/// Ensures that only trailing positional args are non-required.
|
||||
fn ensure_only_trailing_positionals_are_optional(errors: &Errors, fields: &[StructField<'_>]) {
|
||||
let mut first_non_required_span = None;
|
||||
for field in fields {
|
||||
if field.kind == FieldKind::Positional {
|
||||
if let Some(first) = first_non_required_span {
|
||||
if let Some(first) = first_non_required_span
|
||||
&& field.optionality.is_required()
|
||||
{
|
||||
errors.err_span(
|
||||
first,
|
||||
"Only the last positional argument may be `Option`, `Vec`, or defaulted.",
|
||||
"Only trailing positional arguments may be `Option`, `Vec`, or defaulted.",
|
||||
);
|
||||
errors.err(
|
||||
&field.field,
|
||||
"Later non-optional positional argument declared here.",
|
||||
);
|
||||
errors.err(&field.field, "Later positional argument declared here.");
|
||||
return;
|
||||
}
|
||||
if !field.optionality.is_required() {
|
||||
|
||||
@@ -58,8 +58,8 @@ struct Repack {
|
||||
no_compress: bool,
|
||||
#[argh(positional)]
|
||||
img: Utf8CString,
|
||||
#[argh(positional, default = r#"Utf8CString::from("new-boot.img")"#)]
|
||||
out: Utf8CString,
|
||||
#[argh(positional)]
|
||||
out: Option<Utf8CString>,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
@@ -77,33 +77,24 @@ struct Sign {
|
||||
#[argh(positional)]
|
||||
img: Utf8CString,
|
||||
#[argh(positional)]
|
||||
args: Vec<Utf8CString>,
|
||||
name: Option<Utf8CString>,
|
||||
#[argh(positional)]
|
||||
cert: Option<Utf8CString>,
|
||||
#[argh(positional)]
|
||||
key: Option<Utf8CString>,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "extract")]
|
||||
struct Extract {
|
||||
#[argh(positional)]
|
||||
payload: Utf8CString,
|
||||
#[argh(positional)]
|
||||
partition: Option<Utf8CString>,
|
||||
#[argh(positional)]
|
||||
outfile: Option<Utf8CString>,
|
||||
}
|
||||
|
||||
impl FromArgs for Extract {
|
||||
fn from_args(_command_name: &[&str], args: &[&str]) -> Result<Self, EarlyExit> {
|
||||
let mut parse = PositionalArgParser(args.iter());
|
||||
Ok(Extract {
|
||||
payload: parse.required("payload.bin")?,
|
||||
partition: parse.optional(),
|
||||
outfile: parse.last_optional()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl SubCommand for Extract {
|
||||
const COMMAND: &'static CommandInfo = &CommandInfo {
|
||||
name: "extract",
|
||||
description: "",
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "hexpatch")]
|
||||
struct HexPatch {
|
||||
@@ -186,28 +177,15 @@ impl SubCommand for Compress {
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand, name = "decompress")]
|
||||
struct Decompress {
|
||||
#[argh(positional)]
|
||||
file: Utf8CString,
|
||||
#[argh(positional)]
|
||||
out: Option<Utf8CString>,
|
||||
}
|
||||
|
||||
impl FromArgs for Decompress {
|
||||
fn from_args(_command_name: &[&str], args: &[&str]) -> Result<Self, EarlyExit> {
|
||||
let mut iter = PositionalArgParser(args.iter());
|
||||
Ok(Decompress {
|
||||
file: iter.required("infile")?,
|
||||
out: iter.last_optional()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl SubCommand for Decompress {
|
||||
const COMMAND: &'static CommandInfo = &CommandInfo {
|
||||
name: "decompress",
|
||||
description: "",
|
||||
};
|
||||
}
|
||||
|
||||
fn print_usage(cmd: &str) {
|
||||
eprintln!(
|
||||
r#"MagiskBoot - Boot Image Modification Tool
|
||||
@@ -386,21 +364,24 @@ fn boot_main(cmds: CmdArgs) -> LoggedResult<i32> {
|
||||
img,
|
||||
out,
|
||||
}) => {
|
||||
repack(&img, &out, no_compress);
|
||||
repack(
|
||||
&img,
|
||||
out.as_deref().unwrap_or(cstr!("new-boot.img")),
|
||||
no_compress,
|
||||
);
|
||||
}
|
||||
Action::Verify(Verify { img, cert }) => {
|
||||
if !verify_cmd(&img, cert.as_deref()) {
|
||||
return log_err!();
|
||||
}
|
||||
}
|
||||
Action::Sign(Sign { img, args }) => {
|
||||
let mut iter = args.iter();
|
||||
sign_cmd(
|
||||
&img,
|
||||
iter.next().map(AsRef::as_ref),
|
||||
iter.next().map(AsRef::as_ref),
|
||||
iter.next().map(AsRef::as_ref),
|
||||
)?;
|
||||
Action::Sign(Sign {
|
||||
img,
|
||||
name,
|
||||
cert,
|
||||
key,
|
||||
}) => {
|
||||
sign_cmd(&img, name.as_deref(), cert.as_deref(), key.as_deref())?;
|
||||
}
|
||||
Action::Extract(Extract {
|
||||
payload,
|
||||
|
||||
Reference in New Issue
Block a user