diff --git a/Cargo.toml b/Cargo.toml index 99f2756..362818d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Anthony Cicchetti "] edition = "2021" [dependencies] -clap = "2.34.0" +clap = "3.0.0-beta.5" day_01 = { path = "./day_01" } day_02 = { path = "./day_02" } diff --git a/src/main.rs b/src/main.rs index aa1ad5a..61717eb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,32 +1,81 @@ -extern crate clap; - -use clap::{arg_enum, clap_app, value_t}; use std::error::Error; +use std::fmt::{Debug, Display, Formatter}; use std::fs::File; use std::io::{BufReader, Read}; +use std::str::FromStr; -arg_enum! { - #[derive(Debug)] - enum DaysImplemented { - Day1, - Day2, +use clap::{App, AppSettings::ArgRequiredElseHelp, Arg}; + +#[derive(Debug)] +enum DaysImplemented { + Day1, + Day2, +} + +impl Display for DaysImplemented { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + DaysImplemented::Day1 => { + write!(f, "Day 1") + } + DaysImplemented::Day2 => { + write!(f, "Day 2") + } + } + } +} + +impl FromStr for DaysImplemented { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + match s { + "Day1" => Ok(DaysImplemented::Day1), + "Day2" => Ok(DaysImplemented::Day2), + _ => Err("Not any of days implemented"), + } } } fn main() -> Result<(), Box> { - let matches = clap_app!(AdventOfCode2021 => - (author: "Anthony Cicchetti") - (@setting ArgRequiredElseHelp) - (@arg day_to_execute: -d --day * +takes_value possible_values(&DaysImplemented::variants())) - (@arg part: -p --part * +takes_value possible_values(&["1", "2"])) - (@arg input_file: -f --file {file_exists} * conflicts_with[input_string] +takes_value "Input file") - (@arg input_string: required_unless[input_file] "Input string") - ).get_matches(); - let day: DaysImplemented = - value_t!(matches.value_of("day_to_execute"), DaysImplemented).unwrap(); // Safe unwrap because value is required - let part = value_t!(matches.value_of("part"), u8).unwrap(); - let input = match matches.value_of("input_file") { - None => value_t!(matches.value_of("input_string"), String).unwrap(), + let matches = App::new("AdventOfCode2021") + .author("Anthony Cicchetti") + .setting(ArgRequiredElseHelp) + .arg( + Arg::new("day_to_execute") + .short('d') + .long("day") + .takes_value(true) + .possible_values(vec!["Day1", "Day2"]) + .about("Which day should be executed?"), + ) + .arg( + Arg::new("part") + .short('p') + .long("part") + .takes_value(true) + .possible_values(vec!["1", "2"]) + .about("Which part to execute?"), + ) + .arg( + Arg::new("input_file") + .short('f') + .long("file") + .takes_value(true) + .validator(file_exists) + .conflicts_with("input_string") + .about("Input File"), + ) + .arg( + Arg::new("input_string") + .required_unless_present("input_file") + .about("Input string"), + ) + .get_matches(); + let day: DaysImplemented = matches.value_of_t("day_to_execute").unwrap(); // Safe unwrap because value is required + let part: usize = matches.value_of_t("part").unwrap(); // Same as above + let input: String = match matches.value_of("input_file") { + None => matches.value_of_t("input_string").unwrap(), Some(path) => { let mut s = String::new(); let _ = BufReader::new(File::open(path)?).read_to_string(&mut s); @@ -48,7 +97,7 @@ fn main() -> Result<(), Box> { Ok(()) } -fn file_exists(val: String) -> Result<(), String> { +fn file_exists(val: &str) -> Result<(), String> { if std::fs::metadata(&val).is_ok() { Ok(()) } else {