#[derive(Debug)]
pub enum InclusiveOr<T, U> {
LeftAndRight(T, U),
Left(T),
Right(U),
}
pub type InclusiveOrHomogeneous<T> = InclusiveOr<T, T>;
impl<T, U> InclusiveOr<T, U> {
pub fn get_left(&self) -> Option<&T> {
match self {
InclusiveOr::LeftAndRight(left, _) | InclusiveOr::Left(left) => Some(left),
InclusiveOr::Right(_) => None,
}
}
pub fn get_right(&self) -> Option<&U> {
match self {
InclusiveOr::LeftAndRight(_, right) | InclusiveOr::Right(right) => Some(right),
InclusiveOr::Left(_) => None,
}
}
}
pub trait InclusiveOrExt<T, U> {
fn or_inclusive(self, other: Option<U>) -> Option<InclusiveOr<T, U>>;
}
impl<T, U> InclusiveOrExt<T, U> for Option<T> {
fn or_inclusive(self, other: Option<U>) -> Option<InclusiveOr<T, U>> {
match (self, other) {
(None, None) => None,
(None, Some(right)) => Some(InclusiveOr::Right(right)),
(Some(left), None) => Some(InclusiveOr::Left(left)),
(Some(left), Some(right)) => Some(InclusiveOr::LeftAndRight(left, right)),
}
}
}