common/rust: add UpToTwo type
This commit is contained in:
parent
9b62590517
commit
c7062a05e8
1 changed files with 58 additions and 0 deletions
|
@ -2,4 +2,62 @@
|
|||
|
||||
mod section_range;
|
||||
|
||||
use std::mem;
|
||||
|
||||
pub use section_range::{EmptyRange, InvalidSectionString, SectionRange};
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue