use std::error::Error; use clap::{App, Arg}; use std::fs::File; use std::io::{self, BufRead, BufReader}; type MyResult = Result>; #[derive(Debug)] pub struct Config { files: Vec, 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 { let matches = App::new("cat") .version("0.1.0") .author("perro ") .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> { match filename { "-" => Ok(Box::new(BufReader::new(io::stdin()))), _ => Ok(Box::new(BufReader::new(File::open(filename)?))), } } fn print(_file: &Box, _numbered: &bool, _nonblank: &bool) { // TODO }