summaryrefslogtreecommitdiffstats
path: root/aoc/src/lib.rs
blob: 5fad72d88612269838065ec43e0649d6a5633f34 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use clap::Parser;
use std::fs::File;
use std::io;
use std::io::{BufRead, BufReader, Read};

#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
    #[arg(short, long, default_value = "-")]
    file: String,

    #[arg(short, long, default_value_t = 1)]
    part: u8,
}

pub trait Day {
    fn example_input(&self) -> &'static str;
    fn example_result_part_1(&self) -> &'static str;
    fn example_result_part_2(&self) -> &'static str;

    fn read_lines(&self, input:  BufReader<Box<dyn Read>>) -> Vec<String> {
        let mut lines = Vec::new();

        for line in input.lines() {
            match line {
                Ok(content) => lines.push(content),
                Err(e) => eprintln!("Error reading line: {}", e),
            }
        }

        lines
    }

    fn part_1(&self, input: BufReader<Box<dyn Read>>) -> String;
    fn part_2(&self, input: BufReader<Box<dyn Read>>) -> String;
}

pub fn main(day: &dyn Day) {
    let args = Args::parse();

    let reader: Box<dyn Read> = if args.file == "-" {
        Box::new(io::stdin())
    } else {
        Box::new(File::open(&args.file).expect("Failed to open file"))
    };

    let buffer = BufReader::new(reader);

    let result: String;
    if args.part == 1 {
        result = day.part_1(buffer);
    } else {
        result = day.part_2(buffer);
    }

    println!("Result: {result}")
}

pub fn test_day<T: Day>(day: &T) {
    use std::io::Cursor;
    use std::io::{BufReader, Read};

    let example_input = day.example_input();

    // Test Part 1
    let input = BufReader::new(Box::new(Cursor::new(example_input)) as Box<dyn Read>);
    let output = day.part_1(input);
    assert_eq!(output.trim(), day.example_result_part_1(), "Part 1 failed");

    // Test Part 2
    let input = BufReader::new(Box::new(Cursor::new(example_input)) as Box<dyn Read>);
    let output = day.part_2(input);
    assert_eq!(output.trim(), day.example_result_part_2(), "Part 2 failed");
}