119 lines
3.6 KiB
Rust
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))
|
|
}
|
|
}
|