diff options
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/main.rs | 37 |
2 files changed, 37 insertions, 1 deletions
@@ -7,3 +7,4 @@ edition = "2021" [dependencies] clap = { version = "4.0.2", features = ["derive"] } +thiserror = "1.0.37" diff --git a/src/main.rs b/src/main.rs index d1d7e5d..45ebbb6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,47 @@ use clap::Parser; +use std::fs::read; +use std::path::PathBuf; fn main() { + if let Err(e) = fallible_main() { + eprintln!("ERROR: {}", e); + } +} + +fn fallible_main() -> Result<(), HelloError> { let args = Args::parse(); - println!("hello, {}", args.whom); + println!("hello, {}", args.whom()?); + Ok(()) } #[derive(Parser)] struct Args { #[clap(default_value = "world")] whom: String, + + #[clap(short, long)] + filename: Option<PathBuf>, +} + +impl Args { + fn whom(&self) -> Result<String, HelloError> { + if let Some(filename) = &self.filename { + let data = read(&filename) + .map_err(|e| HelloError::Read(filename.clone(), e))?; + let whom = String::from_utf8(data) + .map_err(|e| HelloError::Utf8(filename.clone(), e))?; + Ok(whom.trim().to_string()) + } else { + Ok(self.whom.clone()) + } + } +} + +#[derive(Debug, thiserror::Error)] +enum HelloError { + #[error("failed to read file {0}")] + Read(PathBuf, #[source] std::io::Error), + + #[error("failed to parse file {0} as UTF-8")] + Utf8(PathBuf, #[source] std::string::FromUtf8Error), } |