advent-of-code-2021/src/main.rs
zendesk-acicchetti eec26b35d6 Day scaffolding
2021-12-17 14:35:50 -05:00

119 lines
3.6 KiB
Rust

use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
use std::fs::File;
use std::io::{BufReader, Read};
use std::str::FromStr;
use clap::{App, AppSettings::ArgRequiredElseHelp, Arg};
#[derive(Debug)]
enum DaysImplemented {
Day1,
Day2,
Day3,
Day4,
}
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")
}
DaysImplemented::Day3 => {
write!(f, "Day 3")
}
DaysImplemented::Day4 => {
write!(f, "Day 4")
}
}
}
}
impl FromStr for DaysImplemented {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Day1" => Ok(DaysImplemented::Day1),
"Day2" => Ok(DaysImplemented::Day2),
"Day3" => Ok(DaysImplemented::Day3),
"Day4" => Ok(DaysImplemented::Day4),
_ => Err("Not any of days implemented"),
}
}
}
fn main() -> Result<(), Box<dyn Error>> {
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", "Day3", "Day4"])
.help("Which day should be executed?"),
)
.arg(
Arg::new("part")
.short('p')
.long("part")
.takes_value(true)
.possible_values(vec!["1", "2"])
.help("Which part to execute?"),
)
.arg(
Arg::new("input_file")
.short('f')
.long("file")
.takes_value(true)
.validator(file_exists)
.conflicts_with("input_string")
.help("Input File"),
)
.arg(
Arg::new("input_string")
.required_unless_present("input_file")
.help("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);
s
}
};
println!("Executing {}, Part {}", day, part);
match (day, part) {
(DaysImplemented::Day1, 1) => println!("{}", day_01::part1(&input)),
(DaysImplemented::Day1, 2) => println!("{}", day_01::part2(&input)),
(DaysImplemented::Day2, 1) => println!("{}", day_02::part1(&input)),
(DaysImplemented::Day2, 2) => println!("{}", day_02::part2(&input)),
(DaysImplemented::Day3, 1) => println!("{}", day_03::part1(&input)),
(DaysImplemented::Day3, 2) => println!("{}", day_03::part2(&input)),
(DaysImplemented::Day4, 1) => println!("{}", day_04::part1(&input)),
_ => {
unimplemented!()
}
};
Ok(())
}
fn file_exists(val: &str) -> Result<(), String> {
if std::fs::metadata(&val).is_ok() {
Ok(())
} else {
Err(format!("File at {} doesn't exist", &val))
}
}