command-line-rust/exercises/ex03/src/lib.rs

71 lines
1.9 KiB
Rust

use std::error::Error;
use clap::{App, Arg};
use std::fs::File;
use std::io::{self, BufRead, BufReader};
type MyResult<T> = Result<T, Box<dyn Error>>;
#[derive(Debug)]
pub struct Config {
files: Vec<String>,
numbered: bool,
nonblank: bool,
}
pub fn run(config: Config) -> MyResult<()> {
for filename in config.files {
match open(&filename) {
Err(err) => eprintln!("Failed to open {}: {}", filename, err),
Ok(file) => print(&file, &config.numbered, &config.nonblank),
}
}
Ok(())
}
pub fn get_args() -> MyResult<Config> {
let matches = App::new("cat")
.version("0.1.0")
.author("perro <hi@perrotuerto.blog>")
.about("Rust cat")
.arg(
Arg::with_name("files")
.value_name("ARCHIVOS")
.help("Archivos de entrada")
.multiple(true)
.default_value("-"),
)
.arg(
Arg::with_name("numbered")
.short("n")
.long("number")
.help("Imprime números de línea")
.takes_value(false)
.conflicts_with("nonblank"),
)
.arg(
Arg::with_name("nonblank")
.short("b")
.long("number-nonblank")
.help("Imprime números de línea solo si no están vacías")
.takes_value(false),
)
.get_matches();
Ok(Config {
files: matches.values_of_lossy("files").unwrap(),
numbered: matches.is_present("numbered"),
nonblank: matches.is_present("nonblank"),
})
}
fn open(filename: &str) -> MyResult<Box<dyn BufRead>> {
match filename {
"-" => Ok(Box::new(BufReader::new(io::stdin()))),
_ => Ok(Box::new(BufReader::new(File::open(filename)?))),
}
}
fn print(_file: &Box<dyn BufRead>, _numbered: &bool, _nonblank: &bool) {
// TODO
}