aoc_runner_internal/
lib.rs1extern crate serde;
2extern crate serde_derive;
3extern crate serde_json;
4
5use serde_derive::*;
6use std::cmp::Ordering;
7use std::error;
8use std::fs;
9use std::iter::FromIterator;
10use std::ops::Deref;
11use std::ops::DerefMut;
12use std::str::FromStr;
13
14#[derive(Debug, Hash, Eq, PartialEq, Copy, Clone, Serialize, Deserialize, Ord, PartialOrd)]
15pub struct Day(pub u8);
16
17impl FromStr for Day {
18 type Err = String;
19
20 fn from_str(day: &str) -> Result<Self, Self::Err> {
21 let slice = if day.len() < 4 || &day[..3] != "day" {
22 &day[..]
23 } else {
24 &day[3..]
25 };
26
27 slice
28 .parse()
29 .map_err(|e| format!("Failed to parse {}: {:?}", day, e))
30 .and_then(|d| {
31 if d == 0 || d > 25 {
32 Err(format!("day {} is not between 0 and 25", d))
33 } else {
34 Ok(Day(d))
35 }
36 })
37 }
38}
39
40#[derive(Debug, Hash, Eq, PartialEq, Copy, Clone, Serialize, Deserialize, Ord, PartialOrd)]
41pub struct Part(pub u8);
42
43impl FromStr for Part {
44 type Err = String;
45
46 fn from_str(part: &str) -> Result<Self, Self::Err> {
47 Ok(match part {
48 "part1" | "1" => Part(1),
49 "part2" | "2" => Part(2),
50 _ => return Err(format!("Failed to parse part: {}", part)),
51 })
52 }
53}
54
55#[derive(Debug, Hash, Eq, PartialEq, Clone, Serialize, Deserialize)]
56pub struct DayPart {
57 pub day: Day,
58 pub part: Part,
59 pub name: Option<String>,
60}
61
62impl DayPart {
63 pub fn without_name(&self) -> DayPart {
64 DayPart {
65 name: None,
66 day: self.day,
67 part: self.part,
68 }
69 }
70}
71
72impl PartialOrd for DayPart {
73 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
74 Some(self.cmp(&other))
75 }
76}
77
78impl Ord for DayPart {
79 fn cmp(&self, other: &Self) -> Ordering {
80 self.day
81 .cmp(&other.day)
82 .then(self.part.cmp(&other.part))
83 .then(self.name.cmp(&other.name))
84 }
85}
86
87#[derive(Serialize, Deserialize, Debug)]
88pub struct DayParts {
89 pub year: u32,
90 parts: Vec<DayPart>,
91}
92
93impl DayParts {
94 pub fn save(&self) -> Result<(), Box<error::Error>> {
95 fs::create_dir_all("target/aoc")?;
96 let f = fs::File::create("target/aoc/completed.json")?;
97
98 serde_json::to_writer_pretty(f, &self)?;
99
100 Ok(())
101 }
102
103 pub fn load() -> Result<Self, Box<error::Error>> {
104 let f = fs::File::open("target/aoc/completed.json")?;
105
106 Ok(serde_json::from_reader(f)?)
107 }
108}
109
110impl Deref for DayParts {
111 type Target = [DayPart];
112
113 fn deref(&self) -> &[DayPart] {
114 &self.parts
115 }
116}
117
118impl DerefMut for DayParts {
119 fn deref_mut(&mut self) -> &mut [DayPart] {
120 &mut self.parts
121 }
122}
123
124pub struct DayPartsBuilder {
125 parts: Vec<DayPart>,
126}
127
128impl DayPartsBuilder {
129 pub fn with_year(self, year: u32) -> DayParts {
130 DayParts {
131 year,
132 parts: self.parts,
133 }
134 }
135}
136
137impl FromIterator<DayPart> for DayPartsBuilder {
138 fn from_iter<T: IntoIterator<Item = DayPart>>(iter: T) -> Self {
139 let parts = iter.into_iter().collect();
140 DayPartsBuilder { parts }
141 }
142}