刘一凡
刘一凡

Reputation: 1

Parse input with clap for command line

I attempted to implement the 'cat' command.

use clap::{value_parser, Arg};
use std::error::Error;

type MyResult<T> = Result<T, Box<dyn Error>>;

pub fn run(config: Config) -> MyResult<()> {
    dbg!(config);
    Ok(())
}

#[derive(Debug)]
pub struct Config {
    files: Vec<String>,
    // -n print the line number
    number_lines: bool,
    // -b print the line number only for nonblank lines
    number_nonblank_lines: bool,
}

pub fn get_args() -> MyResult<Config> {
    let matches = clap::Command::new("catr")
        .author("Liu yifan, [email protected]")
        .version("0.1.0")
        .about("Rust cat")
        .arg(
            Arg::new("files")
                .value_name("FILE")
                .help("Input file(s)")
                .num_args(1..)
                .default_value("-")
                .value_delimiter(' '),
        )
        .arg(
            Arg::new("number")
                .short('n')
                .long("number")
                .help("Number lines")
                .conflicts_with("number_nonblank")
                .action(clap::ArgAction::SetTrue),
        )
        .arg(
            Arg::new("number_nonblank")
                .short('b')
                .long("number-nonblank")
                .help("Number non-blank lines")
                .action(clap::ArgAction::SetTrue),
        )
        .get_matches();
    Ok(Config {
        files: matches.get_one::<Vec<String>>("files").unwrap().clone(),
        number_lines: matches.get_one::<bool>("number").map_or(false, |&v| v),
        number_nonblank_lines: matches
            .get_one::<bool>("number_nonblank")
            .map_or(false, |&v| v),
    })
}

but encountered an error when executing ./catr a.txt b.txt.

~/Desktop/work/github/command-line-rust/target/debug master ?5 ❯ ./catr a.txt b.txt                                                              10:03:15 下午

thread 'main' panicked at catr/src/lib.rs:50:14:

Mismatch between definition and access of `files`. Could not downcast to alloc::vec::Vec<alloc::string::String>, need to downcast to alloc::string::String

note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

It seems there's an issue with this sentence:

files: matches.get_one::<Vec<String>>("files").unwrap().clone()

How can I address it?

Upvotes: 0

Views: 106

Answers (0)

Related Questions