Hi,
I am an experienced java developer and new to Rust. Since I started learning Rust I try to write idiomatic Rust but the old habits of the past are still haunting me!
In the following code snippet, I try to parse a cmd line argument parse and validate it as an existing directory and based on the results create a trait implementation and finally call its method. I use the match early return technique and method chaining. I have also thought to try polymorphism (just for learning) but it backfired. It took me a while to get the map_or_else closure returns to pass compilation. I guess the Box polymorphic return is excessive. I could use an if-else statement to avoid polymorphism. So is there a better way to write this logic? Thank you in advance for your input!
pub trait Printer {
fn print(&self, templates: &[Template], ctx: &Context) -> Result<(), String>;
}
pub struct ConsolePrinter {}
impl Printer for ConsolePrinter { ... }
pub struct FilePrinter {
dir: PathBuf,
}
impl Printer for FilePrinter { ... }
fn main() {
...
match args.first().map(|dir| PathBuf::from(dir)) {
Some(path) => if !path.is_dir() {
return Err(format!("Path is not a directory: {}", path.display()));
} else if !path.exists() {
return Err(format!("Directory doesn't exist: {}", path.display()));
} else { Some(path) },
None => None,
}.map_or_else(
|| Box::new(ConsolePrinter::new()) as Box<dyn Printer>,
|p| Box::new(FilePrinter::new(p)))
.print(release.templates(), &context)
}