cat/cat.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
//! You can open files as part of parsing process too, might not be the best idea though
//! because depending on a context `bpaf` might need to evaluate some parsers multiple times.
//!
//! Main motivation for this example is that you can open a file as part of the argument parsing
//! and give a reader directly to user. In practice to replicate `cat`'s behavior you'd accept
//! multiple files with `many` and open them one by one in your code.
use bpaf::*;
use std::{
ffi::OsString,
fs::File,
io::{stdin, BufRead, BufReader, Read},
};
fn main() {
let file = positional::<OsString>("FILE")
.help("File name to concatenate, with no FILE or when FILE is -, read standard input")
.optional()
.parse::<_, Box<dyn Read>, std::io::Error>(|path| {
Ok(if let Some(path) = path {
if path == "-" {
Box::new(stdin())
} else {
Box::new(File::open(path)?)
}
} else {
Box::new(stdin())
})
})
.to_options()
.descr("Concatenate a file to standard output")
.run();
let reader = BufReader::new(file);
for line in reader.lines() {
println!("{}", line.unwrap());
}
}