1use std::fmt::Display;
2use std::fs::File;
3use std::time::Instant;
4
5use scanf::sscanf;
6
7use client::AocClient;
8
9use crate::input_path::get_day_path;
10use crate::input_type::InputType;
11
12pub mod input_type;
13pub mod util;
14
15mod client;
16mod input_path;
17
18#[macro_export]
19macro_rules! run_test {
20 ($e:expr) => {
21 use aoc_lib::input_type::InputType;
22 use aoc_lib::run;
23 run(file!(), $e, InputType::Test);
24 };
25}
26
27#[macro_export]
28macro_rules! run_real {
29 ($e:expr) => {
30 use aoc_lib::input_type::InputType;
31 use aoc_lib::run;
32 run(file!(), $e, InputType::Real);
33 };
34}
35
36pub fn run<F, R>(src: &str, f: F, input_type: InputType)
37where
38 F: Fn(String) -> R,
39 R: Display,
40{
41 let mut year: u16 = 0;
42 let mut day: u8 = 0;
43 sscanf!(src, "src/year{}/day{}.rs", year, day).unwrap();
44 let input = match input_type {
45 InputType::Real => AocClient::new(year).get_input(day),
46 InputType::Test => {
47 let file = &get_day_path(year, day, input_type)
48 .to_str()
49 .unwrap()
50 .to_string();
51 std::fs::read_to_string(file).unwrap_or_else(|e| {
52 println!("Failed to find {file}");
53 match File::create(file) {
54 Ok(_) => {
55 println!("Created empty file: {file}");
56 println!("Place your test data in there and re-run");
57 }
58 Err(_) => println!("Error: {e}"),
59 }
60 String::new()
61 })
62 }
63 };
64 if input.is_empty() {
65 return;
66 }
67 let timer = Instant::now();
68 let r = f(input);
69 let elapsed = timer.elapsed();
70 println!("Time: {:?}", elapsed);
71 println!("Output: {}", r);
72}