-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproblem.rs
62 lines (52 loc) · 1.66 KB
/
problem.rs
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
use std::ops::Index;
use crate::meta::Part;
use crate::meta::Solution;
use super::solution::ReturnValue;
#[repr(transparent)]
pub struct Problem([Option<&'static dyn Solution>; 2]);
impl Problem {
#[inline]
pub const fn part(&self, part: Part) -> Option<&'static dyn Solution> {
let idx = part.as_u8() as usize - 1;
self.0[idx]
}
pub fn parts(&self) -> impl Iterator<Item = (Part, &dyn Solution)> {
Part::iter().filter_map(|part| self.part(part).map(|solution| (part, solution)))
}
#[allow(dead_code, reason = "Sometimes unused depending on solution progress")]
#[inline]
pub(crate) const fn unsolved() -> Self {
Self([None, None])
}
#[allow(dead_code, reason = "Sometimes unused depending on solution progress")]
#[inline]
pub(crate) const fn partially_solved<F, R>(part_one: &'static F) -> Self
where
F: Fn(&str) -> R,
R: ReturnValue,
{
Self([Some(part_one as &dyn Solution), None])
}
#[allow(dead_code, reason = "Sometimes unused depending on solution progress")]
#[inline]
pub(crate) const fn solved<F1, R1, F2, R2>(part_one: &'static F1, part_two: &'static F2) -> Self
where
F1: Fn(&str) -> R1,
R1: ReturnValue,
F2: Fn(&str) -> R2,
R2: ReturnValue,
{
Self([
Some(part_one as &dyn Solution),
Some(part_two as &dyn Solution),
])
}
}
impl Index<Part> for Problem {
type Output = dyn Solution;
#[inline]
fn index(&self, part: Part) -> &Self::Output {
self.part(part)
.unwrap_or_else(move || panic!("Haven't solved part {part} yet"))
}
}