use std::{ fs::File, io::{self, BufRead, BufReader, ErrorKind, Write}, path::PathBuf, }; use scurvy::{ Argument, Scurvy, formula::{PathFormula, UsizeFormula}, }; pub fn main() { let args = vec![ Argument::new(&["infile", "ifile"]).arg("path"), Argument::new(&["line-number", "ln"]).arg("line#"), Argument::new(&["outfile", "ofile"]).arg("path"), ]; let scurvy = Scurvy::make(args); if scurvy.should_print_help() { println!("{HELP_STR}"); return; } let input = scurvy.parse_req("infile", PathFormula::new()); let output = scurvy.parse_req("outfile", PathFormula::new()); let line_number = scurvy.parse_req("line-number", UsizeFormula::new().bounds(1..)); if let Err(e) = do_work(input, output, line_number) { eprintln!("{e}"); std::process::exit(-1); } } fn do_work(input: PathBuf, output: PathBuf, line_number: usize) -> io::Result<()> { let bufr = BufReader::new(File::open(input)?); let mut out = File::create(output)?; match bufr.lines().nth(line_number) { Some(line) => { out.write_all((line?).as_bytes())?; Ok(()) } None => Err(io::Error::from(ErrorKind::UnexpectedEof)), } } // Tab width is usually eight in terminals. Our max line-length for an options // name line is 72, the help-text itself is 66 const HELP_STR: &'static str = "\ usage: copyline ifile= ofile= ln= ARGUMENTS infile= | ifile= Input file path. Where we read the line from outfile= | ofile= Output file path. Where we write the line to. line-number= | ln= The line you want, starting at 1. ";