advent-of-code/common/rust/src/lib.rs

64 lines
1.3 KiB
Rust
Raw Normal View History

2022-12-04 17:41:57 +01:00
#![warn(clippy::pedantic)]
mod section_range;
2022-12-04 21:29:57 +01:00
use std::mem;
2022-12-04 17:41:57 +01:00
pub use section_range::{EmptyRange, InvalidSectionString, SectionRange};
2022-12-04 21:29:57 +01:00
pub enum UpToTwo<T> {
Zero,
One(T),
Two(T, T),
}
impl<T> UpToTwo<T> {
pub fn is_empty(&self) -> bool {
matches!(self, UpToTwo::Zero)
}
pub fn first(&self) -> Option<&T> {
match self {
UpToTwo::Zero => None,
UpToTwo::One(x) | UpToTwo::Two(x, _) => Some(x),
}
}
pub fn second(&self) -> Option<&T> {
match self {
UpToTwo::Zero | UpToTwo::One(_) => None,
UpToTwo::Two(_, x) => Some(x),
}
}
}
impl<T> IntoIterator for UpToTwo<T> {
type Item = T;
type IntoIter = UpToTwoIter<T>;
fn into_iter(self) -> Self::IntoIter {
UpToTwoIter(self)
}
}
pub struct UpToTwoIter<T>(UpToTwo<T>);
impl<T> Iterator for UpToTwoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let mut content = UpToTwo::Zero;
mem::swap(&mut self.0, &mut content);
let (ret, mut content) = match content {
UpToTwo::Zero => (None, UpToTwo::Zero),
UpToTwo::One(x) => (Some(x), UpToTwo::Zero),
UpToTwo::Two(x, y) => (Some(x), UpToTwo::One(y)),
};
mem::swap(&mut self.0, &mut content);
ret
}
}