Struct Condition

Source
pub struct Condition<'a, T>(/* private fields */);
Expand description

The condition argument with which to branch the parser. Used with CommandLineParser::branch.

There is an implicit (non-compile time) requirement for the type T of a Condition:

The implementations of std::str::FromStr must invert std::fmt::Display.

This sounds scary and onerous, but most types will naturally adhere to this requirement. Consider rusts implementation for bool, where this is requirement holds:

assert_eq!(bool::from_str("true").unwrap().to_string(), "true");
assert_eq!(bool::from_str("false").unwrap().to_string(), "false");

However, not all types will necessarily adhere to this requirement. Observe the following example enum:

// Implement FromStr to be case-insensitive.
// Implement Display.
enum FooBar {
    Foo,
    Bar,
}
assert_eq!(FooBar::from_str("Foo").unwrap().to_string(), "Foo");
// FromStr does not invert Display!
assert_ne!(FooBar::from_str("foo").unwrap().to_string(), "foo");

Implementations§

Source§

impl<'a, T> Condition<'a, T>
where T: FromStr + Display,

Source

pub fn new(value: Scalar<'a, T>, name: &'static str) -> Condition<'a, T>

Create a condition parameter.

§Example
use blarg::{Condition, Scalar};
use std::str::FromStr;

// Be sure to implement `std::str::FromStr` so that it inverts `std::fmt::Display`.
enum FooBar {
    Foo,
    Bar,
}

let mut foo_bar: FooBar = FooBar::Foo;
Condition::new(Scalar::new(&mut foo_bar), "foo_bar");
// .. parse()
match foo_bar {
    FooBar::Foo => println!("Do foo'y things."),
    FooBar::Bar => println!("Do bar'y things."),
};
Examples found in repository?
examples/foo_bar.rs (line 68)
54fn main() {
55    let mut verbose: bool = false;
56    let mut foo_bar = FooBar::Foo;
57    let mut initial: Option<u32> = None;
58    let mut countries: HashSet<Country> = HashSet::default();
59    let mut items: Vec<u32> = Vec::default();
60
61    let ap = CommandLineParser::new("foo_bar");
62    let parser = ap
63        .add(
64            Parameter::option(Switch::new(&mut verbose, true), "verbose", Some('v'))
65                .help("Do dee doo."),
66        )
67        .branch(
68            Condition::new(Scalar::new(&mut foo_bar), "foo_bar")
69                .choice(FooBar::Foo, "123 abc let's make this one medium long.")
70                .choice(FooBar::Bar, "456 def let's make this one multiple sentences.  We're really stretching here HAAAAAAAA HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!")
71                .help("foo'y bar'y stuff")
72                .meta(vec!["a", "b", "c"]),
73        )
74        .command(FooBar::Foo, |sub| {
75            sub.add(Parameter::option(
76                Optional::new(&mut initial),
77                "initial",
78                None,
79            ))
80            .add(
81                Parameter::argument(Collection::new(&mut items, Nargs::Any), "item")
82                    .help("The items."),
83            )
84        })
85        .command(FooBar::Bar, |sub| {
86            sub.add(Parameter::option(
87                Collection::new(&mut countries, Nargs::AtLeastOne),
88                "country",
89                None,
90            ))
91        })
92        .build();
93    parser.parse();
94    println!("Items: {items:?}");
95    execute(verbose, foo_bar, initial, countries, items);
96}
More examples
Hide additional examples
examples/dynamic_sub_command.rs (line 13)
4fn main() {
5    let contains_dynamic_x = env::var("DYNAMIC_X").is_ok();
6    let contains_dynamic_y = env::var("DYNAMIC_Y").is_ok();
7
8    let mut sub: u32 = 0;
9    let mut arg_0: bool = false;
10    let mut arg_1: bool = false;
11    let mut arg_2: bool = false;
12
13    let mut condition = Condition::new(Scalar::new(&mut sub), "sub")
14        // "0" is an undocumented sub-command, but will only available when environment contains `DYNAMIC_X`.
15        // "1" is a regular sub-command.
16        .choice(1, "the one sub-command");
17
18    if contains_dynamic_y {
19        // "2" is a sub-command that will only be available when the environment contains `DYNAMIC_Y`.
20        condition = condition.choice(2, "the two sub-command");
21    }
22
23    let clp = CommandLineParser::new("sub-command");
24    let mut clp = clp.branch(condition).command(1, |sub_command| {
25        sub_command.add(Parameter::argument(Scalar::new(&mut arg_1), "arg"))
26    });
27
28    if contains_dynamic_x {
29        clp = clp.command(0, |sub_command| {
30            sub_command.add(Parameter::argument(Scalar::new(&mut arg_0), "arg"))
31        });
32    }
33
34    if contains_dynamic_y {
35        clp = clp.command(2, |sub_command| {
36            sub_command.add(Parameter::argument(Scalar::new(&mut arg_2), "arg"))
37        });
38    }
39
40    let parser = clp.build();
41
42    parser.parse();
43
44    println!("Used sub-command '{sub}'.");
45    match sub {
46        0 => {
47            println!("arg_0: {arg_0}");
48            assert!(!arg_1);
49            assert!(!arg_2);
50        }
51        1 => {
52            assert!(!arg_0);
53            println!("arg_1: {arg_1}");
54            assert!(!arg_2);
55        }
56        2 => {
57            assert!(!arg_0);
58            assert!(!arg_1);
59            println!("arg_2: {arg_2}");
60        }
61        _ => {
62            panic!("impossible - the parser will reject any variants not specified via `add(..)`.")
63        }
64    }
65}
examples/demo_sub_command.rs (line 13)
3fn main() {
4    let mut sub: u32 = 0;
5    let mut arg_0: bool = false;
6    let mut opt_0: bool = false;
7    let mut arg_1: bool = false;
8
9    let clp = CommandLineParser::new("sub-command");
10    let parser = clp
11        .about("Describe the base command line parser.  Let's make it a little long for fun.")
12        .branch(
13            Condition::new(Scalar::new(&mut sub), "sub")
14                // "0" is an undocumented sub-command.
15                // "1" is a regular sub-command.
16                .choice(1, "the one sub-command")
17                // "2" is a regular sub-command.
18                .choice(2, "the two sub-command")
19                // "3" is a false sub-command.
20                // It will appear in the documentation, but only those specified via `command(..)` actually affect the program structure.
21                .choice(3, "the three sub-command"),
22        )
23        .command(0, |sub_command| {
24            sub_command
25                .about("Describe the 0 sub-command parser.  Let's make it a little long for fun.")
26                .add(Parameter::argument(Scalar::new(&mut arg_0), "arg"))
27                .add(Parameter::option(
28                    Switch::new(&mut opt_0, true),
29                    "opt",
30                    None,
31                ))
32        })
33        .command(1, |sub_command| {
34            sub_command
35                .about("Describe the 1 sub-command parser.")
36                .add(Parameter::argument(Scalar::new(&mut arg_1), "arg"))
37        })
38        // Specify an argument-less & option-less sub-command by leaving the 'sub' untouched.
39        .command(2, |sub_command| sub_command)
40        // Since we never add "3", it isn't a true sub-command.
41        .build();
42
43    parser.parse();
44
45    println!("Used sub-command '{sub}'.");
46    match sub {
47        0 => {
48            println!("arg_0: {arg_0}");
49            println!("opt_0: {opt_0}");
50            assert!(!arg_1);
51        }
52        1 => {
53            assert!(!arg_0);
54            assert!(!opt_0);
55            println!("arg_1: {arg_1}");
56        }
57        2 => {
58            assert!(!arg_0);
59            assert!(!opt_0);
60            assert!(!arg_1);
61            println!("argument-less & option-less");
62        }
63        _ => {
64            panic!(
65                "impossible - the parser will reject any variants not specified via `command(..)`."
66            )
67        }
68    }
69}
Source

pub fn help(self, description: impl Into<String>) -> Condition<'a, T>

Document the help message for this sub-command condition. If repeated, only the final message will apply to the sub-command condition.

A help message describes the condition in full sentence/paragraph format. We recommend allowing blarg to format this field (ex: it is not recommended to use line breaks '\n').

See also:

§Example
use blarg::{Condition, Scalar};

let mut case: u32 = 0;
Condition::new(Scalar::new(&mut case), "case")
    .help("--this will get discarded--")
    .help("Choose the 'case' to execute.  Description may include multiple sentences.");
Examples found in repository?
examples/foo_bar.rs (line 71)
54fn main() {
55    let mut verbose: bool = false;
56    let mut foo_bar = FooBar::Foo;
57    let mut initial: Option<u32> = None;
58    let mut countries: HashSet<Country> = HashSet::default();
59    let mut items: Vec<u32> = Vec::default();
60
61    let ap = CommandLineParser::new("foo_bar");
62    let parser = ap
63        .add(
64            Parameter::option(Switch::new(&mut verbose, true), "verbose", Some('v'))
65                .help("Do dee doo."),
66        )
67        .branch(
68            Condition::new(Scalar::new(&mut foo_bar), "foo_bar")
69                .choice(FooBar::Foo, "123 abc let's make this one medium long.")
70                .choice(FooBar::Bar, "456 def let's make this one multiple sentences.  We're really stretching here HAAAAAAAA HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!")
71                .help("foo'y bar'y stuff")
72                .meta(vec!["a", "b", "c"]),
73        )
74        .command(FooBar::Foo, |sub| {
75            sub.add(Parameter::option(
76                Optional::new(&mut initial),
77                "initial",
78                None,
79            ))
80            .add(
81                Parameter::argument(Collection::new(&mut items, Nargs::Any), "item")
82                    .help("The items."),
83            )
84        })
85        .command(FooBar::Bar, |sub| {
86            sub.add(Parameter::option(
87                Collection::new(&mut countries, Nargs::AtLeastOne),
88                "country",
89                None,
90            ))
91        })
92        .build();
93    parser.parse();
94    println!("Items: {items:?}");
95    execute(verbose, foo_bar, initial, countries, items);
96}
Source

pub fn meta(self, description: Vec<impl Into<String>>) -> Condition<'a, T>

Document the meta message(s) for this sub-command condition. If repeated, only the final message will apply to the sub-command condition.

Meta message(s) describe short format extra details about the condition. We recommend non-sentence information for this field.

See also:

§Example
use blarg::{Condition, Scalar};

let mut case: u32 = 0;
Condition::new(Scalar::new(&mut case), "case")
    .meta(vec!["--this will get discarded--"])
    .meta(vec!["final extra", "details"]);
Examples found in repository?
examples/foo_bar.rs (line 72)
54fn main() {
55    let mut verbose: bool = false;
56    let mut foo_bar = FooBar::Foo;
57    let mut initial: Option<u32> = None;
58    let mut countries: HashSet<Country> = HashSet::default();
59    let mut items: Vec<u32> = Vec::default();
60
61    let ap = CommandLineParser::new("foo_bar");
62    let parser = ap
63        .add(
64            Parameter::option(Switch::new(&mut verbose, true), "verbose", Some('v'))
65                .help("Do dee doo."),
66        )
67        .branch(
68            Condition::new(Scalar::new(&mut foo_bar), "foo_bar")
69                .choice(FooBar::Foo, "123 abc let's make this one medium long.")
70                .choice(FooBar::Bar, "456 def let's make this one multiple sentences.  We're really stretching here HAAAAAAAA HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!")
71                .help("foo'y bar'y stuff")
72                .meta(vec!["a", "b", "c"]),
73        )
74        .command(FooBar::Foo, |sub| {
75            sub.add(Parameter::option(
76                Optional::new(&mut initial),
77                "initial",
78                None,
79            ))
80            .add(
81                Parameter::argument(Collection::new(&mut items, Nargs::Any), "item")
82                    .help("The items."),
83            )
84        })
85        .command(FooBar::Bar, |sub| {
86            sub.add(Parameter::option(
87                Collection::new(&mut countries, Nargs::AtLeastOne),
88                "country",
89                None,
90            ))
91        })
92        .build();
93    parser.parse();
94    println!("Items: {items:?}");
95    execute(verbose, foo_bar, initial, countries, items);
96}

Trait Implementations§

Source§

impl<'a, T> Choices<T> for Condition<'a, T>
where T: FromStr + Display,

Source§

fn choice(self, variant: T, description: impl Into<String>) -> Condition<'a, T>

Document a choice’s help message for the sub-command condition. If repeated for the same variant of T, only the final message will apply to the sub-command condition. Repeat using different variants to document multiple choices. Needn’t be exhaustive.

A choice help message describes the variant in full sentence/paragraph format. We recommend allowing blarg to format this field (ex: it is not recommended to use line breaks '\n').

Notice, the documented or un-documented choices do not affect the actual command parser semantics. To actually limit the command parser semantics, be sure to use an enum.

See also:

§Example
use blarg::{prelude::*, Condition, Scalar};
use std::str::FromStr;

// Be sure to implement `std::str::FromStr` so that it inverts `std::fmt::Display`.
enum FooBar {
    Foo,
    Bar,
}

let mut foo_bar: FooBar = FooBar::Foo;
Condition::new(Scalar::new(&mut foo_bar), "foo_bar")
    .choice(FooBar::Foo, "--this will get discarded--")
    .choice(FooBar::Foo, "Do foo'y things.")
    .choice(FooBar::Bar, "Do bar'y things.  Description may include multiple sentences.");

Auto Trait Implementations§

§

impl<'a, T> Freeze for Condition<'a, T>

§

impl<'a, T> !RefUnwindSafe for Condition<'a, T>

§

impl<'a, T> !Send for Condition<'a, T>

§

impl<'a, T> !Sync for Condition<'a, T>

§

impl<'a, T> Unpin for Condition<'a, T>

§

impl<'a, T> !UnwindSafe for Condition<'a, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more