Skip to main content

wordchipper_cli_util/io/
input_output.rs

1use std::{
2    fs::File,
3    io::{
4        BufRead,
5        BufReader,
6        BufWriter,
7    },
8};
9
10fn squash_standard_io(path: &Option<String>) -> Option<String> {
11    match path {
12        Some(p) if p == "-" => None,
13        Some(p) => Some(p.clone()),
14        None => None,
15    }
16}
17
18/// Input/output argument group.
19#[derive(clap::Args, Debug)]
20pub struct InputArgs {
21    /// Optional input file; "-" may be used to indicate stdin.
22    #[clap(long, default_value = None)]
23    pub input: Option<String>,
24}
25
26impl InputArgs {
27    /// Open a reader for the input.
28    pub fn open_reader(&self) -> Result<Box<dyn BufRead>, Box<dyn std::error::Error>> {
29        Ok(match squash_standard_io(&self.input) {
30            None => Box::new(BufReader::new(std::io::stdin().lock())),
31            Some(p) => Box::new(BufReader::new(File::open(p)?)),
32        })
33    }
34}
35
36/// Output argument group.
37#[derive(clap::Args, Debug)]
38pub struct OutputArgs {
39    /// Optional output file; "-" may be used to indicate stdout.
40    #[clap(long, default_value = None)]
41    pub output: Option<String>,
42}
43
44impl OutputArgs {
45    /// Open a writer for the output.
46    pub fn open_writer(&self) -> Result<Box<dyn std::io::Write>, Box<dyn std::error::Error>> {
47        Ok(match squash_standard_io(&self.output) {
48            Some(p) => Box::new(BufWriter::new(File::create(p)?)),
49            None => Box::new(BufWriter::new(std::io::stdout().lock())),
50        })
51    }
52}