Crate lexarg_error

Crate lexarg_error 

Source
Expand description

Error type for use with lexarg

Inspired by lexopt, lexarg simplifies the formula down further so it can be used for CLI plugin systems.

§Example

use lexarg_error::LexError;

struct Args {
    thing: String,
    number: u32,
    shout: bool,
}

fn parse_args() -> Result<Args, String> {
    #![allow(clippy::enum_glob_use)]
    use lexarg_parser::Arg::*;

    let mut thing = None;
    let mut number = 1;
    let mut shout = false;
    let raw = std::env::args_os().collect::<Vec<_>>();
    let mut parser = lexarg_parser::Parser::new(&raw);
    let bin_name = parser
        .next_raw()
        .expect("nothing parsed yet so no attached lingering")
        .expect("always at least one");
    while let Some(arg) = parser.next_arg() {
        match arg {
            Short("n") | Long("number") => {
                let value = parser.next_flag_value().ok_or_else(|| {
                    LexError::msg("missing required value")
                        .within(arg)
                        .to_string()
                })?;
                number = value
                    .to_str()
                    .ok_or_else(|| {
                        LexError::msg("invalid number")
                            .unexpected(Value(value))
                            .within(arg)
                            .to_string()
                    })?
                    .parse()
                    .map_err(|e| {
                        LexError::msg(e)
                            .unexpected(Value(value))
                            .within(arg)
                            .to_string()
                    })?;
            }
            Long("shout") => {
                shout = true;
            }
            Value(val) if thing.is_none() => {
                thing =
                    Some(val.to_str().ok_or_else(|| {
                        LexError::msg("invalid string").unexpected(arg).to_string()
                    })?);
            }
            Short("h") | Long("help") => {
                println!("Usage: hello [-n|--number=NUM] [--shout] THING");
                std::process::exit(0);
            }
            _ => {
                return Err(LexError::msg("unexpected argument")
                    .unexpected(arg)
                    .to_string());
            }
        }
    }

    Ok(Args {
        thing: thing
            .ok_or_else(|| {
                LexError::msg("missing argument THING")
                    .within(Value(bin_name))
                    .to_string()
            })?
            .to_owned(),
        number,
        shout,
    })
}

fn main() -> Result<(), String> {
    let args = parse_args()?;
    let mut message = format!("Hello {}", args.thing);
    if args.shout {
        message = message.to_uppercase();
    }
    for _ in 0..args.number {
        println!("{message}");
    }
    Ok(())
}

Structs§

LexError
Collect context for creating an error