advent_of_code/
input.rs

1#![allow(clippy::redundant_pub_crate)]
2#![allow(unused)]
3
4use std::cell::RefCell;
5
6pub type ResultType = String;
7
8#[derive(Copy, Clone)]
9pub enum Part {
10    One,
11    Two,
12}
13
14pub struct Input<'a> {
15    pub part: Part,
16    pub text: &'a str,
17    #[cfg(feature = "visualization")]
18    pub visualization: RefCell<String>,
19}
20
21#[allow(single_use_lifetimes)]
22#[allow(clippy::needless_lifetimes)]
23impl<'a> Input<'a> {
24    pub const fn is_part_one(&self) -> bool {
25        matches!(self.part, Part::One)
26    }
27
28    pub const fn is_part_two(&self) -> bool {
29        matches!(self.part, Part::Two)
30    }
31
32    pub fn part_values<T>(&self, if_part_one: T, if_part_two: T) -> T {
33        // See https://github.com/rust-lang/rust/issues/66753 for missing_const_for_fn.
34        #![allow(clippy::missing_const_for_fn)]
35        match self.part {
36            Part::One => if_part_one,
37            Part::Two => if_part_two,
38        }
39    }
40
41    #[cfg(test)]
42    #[allow(clippy::missing_const_for_fn)]
43    pub fn part_one(text: &'a str) -> Self {
44        Self {
45            part: Part::One,
46            text,
47            #[cfg(feature = "visualization")]
48            visualization: RefCell::new("".to_string()),
49        }
50    }
51
52    #[cfg(test)]
53    #[allow(clippy::missing_const_for_fn)]
54    pub fn part_two(text: &'a str) -> Self {
55        Self {
56            part: Part::Two,
57            text,
58            #[cfg(feature = "visualization")]
59            visualization: RefCell::new("".to_string()),
60        }
61    }
62}
63
64#[cfg(test)]
65macro_rules! test_part_one {
66    ($input:tt => $expected:expr) => {
67        assert_eq!(solve(&Input::part_one($input)), Ok($expected));
68    };
69}
70#[cfg(test)]
71pub(crate) use test_part_one;
72
73#[cfg(test)]
74macro_rules! test_part_one_no_allocations {
75    ($input:tt => $expected:expr) => {
76        #[cfg(feature = "count-allocations")]
77        {
78            let info = allocation_counter::measure(|| {
79                assert_eq!(solve(&Input::part_one($input)), Ok($expected));
80            });
81            assert_eq!(0, info.count_total);
82        }
83        #[cfg(not(feature = "count-allocations"))]
84        {
85            assert_eq!(solve(&Input::part_one($input)), Ok($expected));
86        }
87    };
88}
89#[cfg(test)]
90pub(crate) use test_part_one_no_allocations;
91
92#[cfg(test)]
93macro_rules! test_part_two {
94    ($input:tt => $expected:expr) => {
95        assert_eq!(solve(&Input::part_two($input)), Ok($expected));
96    };
97}
98#[cfg(test)]
99pub(crate) use test_part_two;
100
101#[cfg(test)]
102macro_rules! test_part_two_no_allocations {
103    ($input:tt => $expected:expr) => {
104        #[cfg(feature = "count-allocations")]
105        {
106            let info = allocation_counter::measure(|| {
107                assert_eq!(solve(&Input::part_two($input)), Ok($expected));
108            });
109            assert_eq!(0, info.count_total);
110        }
111        #[cfg(not(feature = "count-allocations"))]
112        {
113            assert_eq!(solve(&Input::part_two($input)), Ok($expected));
114        }
115    };
116}
117#[cfg(test)]
118pub(crate) use test_part_two_no_allocations;
119
120#[cfg(test)]
121macro_rules! test_part_one_error {
122    ($input:tt => $expected:expr) => {
123        assert_eq!(Err($expected.into()), solve(&Input::part_one($input)));
124    };
125}
126#[cfg(test)]
127pub(crate) use test_part_one_error;
128
129#[cfg(test)]
130macro_rules! test_part_two_error {
131    ($input:tt => $expected:expr) => {
132        assert_eq!(Err($expected.into()), solve(&Input::part_two($input)));
133    };
134}
135#[cfg(test)]
136pub(crate) use test_part_two_error;
137
138pub fn on_error() -> String {
139    "Invalid input".to_string()
140}