use colored::*; use exitfailure::ExitFailure; use failure::ResultExt; use std::io::{self, Read}; use structopt::StructOpt; #[derive(StructOpt)] struct Options { #[structopt(default_value = "Woolf!")] /// What does the wolf say? message: String, #[structopt(short = "d", long = "dead")] /// Make the wolf appear dead dead: bool, #[structopt(short = "i", long = "stdin")] /// Read the message from STDIN instead of the argument stdin: bool, #[structopt(short = "f", long = "file", parse(from_os_str))] /// Load the wolf picture from the specified file wolffile: Option, } fn main() -> Result<(), ExitFailure> { let options = Options::from_args(); let mut message = String::new(); if options.stdin { io::stdin().read_to_string(&mut message)?; } else { message = options.message; }; let eye = if options.dead { "x".bright_red() } else { "o".bright_yellow() }; if message.to_lowercase() == "meow" { eprintln!("The wolf's pride is hurt. Never do it again!") } match &options.wolffile { Some(path) => { let wolf_template = std::fs::read_to_string(path) .with_context(|_| format!("could not read file {:?}", path))?; let wolf_picture = wolf_template .replace("{e}", &eye) .replace("{message}", &message); println!("{}", &wolf_picture); } None => { println!( " {} _ _ / /\\\\ ,'/| / _| |\\-'-'_/_/ __--'/` \\ / \\ / \"{e}. |{e}\"| | \\/ \\_ ___\\ `--._`. \\;// ;-.___,' / ,' _-' ", message.bright_yellow().bold().on_blue(), e = eye.bold() ); } } Ok(()) }