Skip to main content

FromArgs

Trait FromArgs 

Source
pub trait FromArgs: Sized {
    // Required method
    fn from_args(
        command_name: &[&str],
        args: &[&str],
    ) -> Result<Self, EarlyExit>;

    // Provided method
    fn redact_arg_values(
        _command_name: &[&str],
        _args: &[&str],
    ) -> Result<Vec<String>, EarlyExit> { ... }
}
Expand description

Types which can be constructed from a set of commandline arguments.

Required Methods§

Source

fn from_args(command_name: &[&str], args: &[&str]) -> Result<Self, EarlyExit>

Construct the type from an input set of arguments.

The first argument command_name is the identifier for the current command. In most cases, users should only pass in a single item for the command name, which typically comes from the first item from std::env::args(). Implementations however should append the subcommand name in when recursively calling FromArgs::from_args for subcommands. This allows argh to generate correct subcommand help strings.

The second argument args is the rest of the command line arguments.

§Examples

/// Command to manage a classroom.
#[derive(Debug, PartialEq, FromArgs)]
struct ClassroomCmd {
    #[argh(subcommand)]
    subcommands: Subcommands,
}

#[derive(Debug, PartialEq, FromArgs)]
#[argh(subcommand)]
enum Subcommands {
    List(ListCmd),
    Add(AddCmd),
}

/// list all the classes.
#[derive(Debug, PartialEq, FromArgs)]
#[argh(subcommand, name = "list")]
struct ListCmd {
    /// list classes for only this teacher.
    #[argh(option)]
    teacher_name: Option<String>,
}

/// add students to a class.
#[derive(Debug, PartialEq, FromArgs)]
#[argh(subcommand, name = "add")]
struct AddCmd {
    /// the name of the class's teacher.
    #[argh(option)]
    teacher_name: String,

    /// the name of the class.
    #[argh(positional)]
    class_name: String,
}

let args = ClassroomCmd::from_args(
    &["classroom"],
    &["list", "--teacher-name", "Smith"],
).unwrap();
assert_eq!(
   args,
    ClassroomCmd {
        subcommands: Subcommands::List(ListCmd {
            teacher_name: Some("Smith".to_string()),
        })
    },
);

// Help returns an error, but internally returns an `Ok` status.
let early_exit = ClassroomCmd::from_args(
    &["classroom"],
    &["help"],
).unwrap_err();
assert_eq!(
    early_exit,
    argh::EarlyExit {
       output: r#"Usage: classroom <command> [<args>]

Command to manage a classroom.

Options:
  --help, help      display usage information

Commands:
  list              list all the classes.
  add               add students to a class.
"#.to_string(),
       status: Ok(()),
    },
);

// Help works with subcommands.
let early_exit = ClassroomCmd::from_args(
    &["classroom"],
    &["list", "help"],
).unwrap_err();
assert_eq!(
    early_exit,
    argh::EarlyExit {
       output: r#"Usage: classroom list [--teacher-name <teacher-name>]

list all the classes.

Options:
  --teacher-name    list classes for only this teacher.
  --help, help      display usage information
"#.to_string(),
       status: Ok(()),
    },
);

// Incorrect arguments will error out.
let err = ClassroomCmd::from_args(
    &["classroom"],
    &["lisp"],
).unwrap_err();
assert_eq!(
   err,
   argh::EarlyExit {
       output: "Unrecognized argument: lisp\n".to_string(),
       status: Err(()),
    },
);

Provided Methods§

Source

fn redact_arg_values( _command_name: &[&str], _args: &[&str], ) -> Result<Vec<String>, EarlyExit>

Get a String with just the argument names, e.g., options, flags, subcommands, etc, but without the values of the options and arguments. This can be useful as a means to capture anonymous usage statistics without revealing the content entered by the end user.

The first argument command_name is the identifier for the current command. In most cases, users should only pass in a single item for the command name, which typically comes from the first item from std::env::args(). Implementations however should append the subcommand name in when recursively calling FromArgs::from_args for subcommands. This allows argh to generate correct subcommand help strings.

The second argument args is the rest of the command line arguments.

§Examples

/// Command to manage a classroom.
#[derive(FromArgs)]
struct ClassroomCmd {
    #[argh(subcommand)]
    subcommands: Subcommands,
}

#[derive(FromArgs)]
#[argh(subcommand)]
enum Subcommands {
    List(ListCmd),
    Add(AddCmd),
}

/// list all the classes.
#[derive(FromArgs)]
#[argh(subcommand, name = "list")]
struct ListCmd {
    /// list classes for only this teacher.
    #[argh(option)]
    teacher_name: Option<String>,
}

/// add students to a class.
#[derive(FromArgs)]
#[argh(subcommand, name = "add")]
struct AddCmd {
    /// the name of the class's teacher.
    #[argh(option)]
    teacher_name: String,

    /// has the class started yet?
    #[argh(switch)]
    started: bool,

    /// the name of the class.
    #[argh(positional)]
    class_name: String,

    /// the student names.
    #[argh(positional)]
    students: Vec<String>,
}

let args = ClassroomCmd::redact_arg_values(
    &["classroom"],
    &["list"],
).unwrap();
assert_eq!(
    args,
    &[
        "classroom",
        "list",
    ],
);

let args = ClassroomCmd::redact_arg_values(
    &["classroom"],
    &["list", "--teacher-name", "Smith"],
).unwrap();
assert_eq!(
   args,
   &[
        "classroom",
        "list",
        "--teacher-name",
    ],
);

let args = ClassroomCmd::redact_arg_values(
    &["classroom"],
    &["add", "--teacher-name", "Smith", "--started", "Math", "Abe", "Sung"],
).unwrap();
assert_eq!(
    args,
    &[
        "classroom",
        "add",
        "--teacher-name",
        "--started",
        "class_name",
        "students",
        "students",
    ],
);

// `ClassroomCmd::redact_arg_values` will error out if passed invalid arguments.
assert_eq!(
    ClassroomCmd::redact_arg_values(&["classroom"], &["add", "--teacher-name"]),
    Err(argh::EarlyExit {
        output: "No value provided for option '--teacher-name'.\n".into(),
        status: Err(()),
    }),
);

// `ClassroomCmd::redact_arg_values` will generate help messages.
assert_eq!(
    ClassroomCmd::redact_arg_values(&["classroom"], &["help"]),
    Err(argh::EarlyExit {
        output: r#"Usage: classroom <command> [<args>]

Command to manage a classroom.

Options:
  --help, help      display usage information

Commands:
  list              list all the classes.
  add               add students to a class.
"#.to_string(),
        status: Ok(()),
    }),
);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<T: FromArgs> FromArgs for Box<T>

Source§

fn from_args(command_name: &[&str], args: &[&str]) -> Result<Self, EarlyExit>

Source§

fn redact_arg_values( command_name: &[&str], args: &[&str], ) -> Result<Vec<String>, EarlyExit>

Implementors§