This is the pattern I often use when writing command-line programs:
use std::env;
use std::fs::File;
use std::io::{self, Error, Write};
use std::path::PathBuf;
fn main() {
let args = Args::from_env();
let mut output = args.get_output().unwrap();
writeln!(output, "Hello, World!").unwrap();
}
#[derive(Debug)]
struct Args {
/// write to the provided file, or `stdout` when not provided
output: Option<PathBuf>,
}
impl Args {
// I'd usually use clap or structopt for command-line argument parsing...
fn from_env() -> Args {
Args {
output: env::args().nth(1).map(PathBuf::from),
}
}
fn get_output(&self) -> Result<Box<dyn Write>, Error> {
match self.output {
Some(ref path) => File::open(path).map(|f| Box::new(f) as Box<dyn Write>),
None => Ok(Box::new(io::stdout())),
}
}
}