-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpart.rs
97 lines (80 loc) · 2.04 KB
/
part.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use std::fmt::{self, Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
use std::num::ParseIntError;
use std::str::FromStr;
use enum_map::Enum;
use thiserror::Error;
#[derive(PartialEq, Eq, Clone, Copy, Enum)]
pub struct Part(bool);
impl Part {
pub fn iter() -> impl Iterator<Item = Self> {
[Part::ONE, Part::TWO].into_iter()
}
}
impl Debug for Part {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_tuple("Part")
.field(match *self {
Part::ONE => &1u8,
Part::TWO => &2u8,
})
.finish()
}
}
impl Display for Part {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match *self {
Part::ONE => Display::fmt(&1u8, f),
Part::TWO => Display::fmt(&2u8, f),
}
}
}
impl Part {
pub const ONE: Part = Part(true);
pub const TWO: Part = Part(false);
pub const fn as_u8(self) -> u8 {
match self {
Part::ONE => 1,
Part::TWO => 2,
}
}
}
#[derive(Debug, Error)]
pub enum FromU8Error {
#[error("Parts are 1-indexed")]
Zero,
#[error("Invalid part {0}: problems only have two parts.")]
TooHigh(u8),
}
impl TryFrom<u8> for Part {
type Error = FromU8Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Err(FromU8Error::Zero),
1 => Ok(Part::ONE),
2 => Ok(Part::TWO),
3.. => Err(FromU8Error::TooHigh(value)),
}
}
}
#[derive(Debug, Error)]
pub enum ParsePartError {
#[error(transparent)]
NaN(#[from] ParseIntError),
#[error(transparent)]
OutOfRange(#[from] FromU8Error),
}
impl FromStr for Part {
type Err = ParsePartError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let num: u8 = s.parse()?;
let part = num.try_into()?;
Ok(part)
}
}
impl Hash for Part {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_u8(self.as_u8());
}
}
impl nohash_hasher::IsEnabled for Part {}