use super::*;
use quither_proc_macros::quither;
#[quither]
impl<L, R> Quither<L, R> {
#[quither(has_neither && (has_either || has_both))]
pub fn factor_neither(self) -> Option<Quither<L, R, has_either, false, has_both>> {
match self {
#[either]
Self::Left(l) => Some(Quither::<L, R, has_either, false, has_both>::Left(l)),
#[either]
Self::Right(r) => Some(Quither::<L, R, has_either, false, has_both>::Right(r)),
#[neither]
Self::Neither => None,
#[both]
Self::Both(l, r) => Some(Quither::<L, R, has_either, false, has_both>::Both(l, r)),
}
}
}
#[quither]
impl<L, R> Quither<Option<L>, Option<R>> {
pub fn factor_none(
self,
) -> Option<Quither<L, R, { has_both || has_either }, has_neither, has_both>> {
#[allow(unused)]
type Quither2<L, R> = Quither<L, R, { has_both || has_either }, has_neither, has_both>;
match self {
#[either]
Self::Left(Some(l)) => Some(Quither2::Left(l)),
#[either]
Self::Right(Some(r)) => Some(Quither2::Right(r)),
#[both]
Self::Both(Some(l), Some(r)) => Some(Quither2::Both(l, r)),
#[both]
Self::Both(Some(l), None) => Some(Quither2::Left(l)),
#[both]
Self::Both(None, Some(r)) => Some(Quither2::Right(r)),
_ => None,
}
}
}
impl<L, R, E> Either<Result<L, E>, Result<R, E>> {
pub fn factor_err(self) -> Result<Either<L, R>, E> {
match self {
Either::Left(Ok(l)) => Ok(Either::Left(l)),
Either::Right(Ok(r)) => Ok(Either::Right(r)),
Either::Left(Err(e)) | Either::Right(Err(e)) => Err(e),
}
}
}
impl<T, L, R> Either<Result<T, L>, Result<T, R>> {
pub fn factor_ok(self) -> Result<T, Either<L, R>> {
match self {
Either::Left(Err(e)) => Err(Either::Left(e)),
Either::Right(Err(e)) => Err(Either::Right(e)),
Either::Left(Ok(x)) | Either::Right(Ok(x)) => Ok(x),
}
}
}
impl<T, L, R> Either<(T, L), (T, R)> {
pub fn factor_first(self) -> (T, Either<L, R>) {
match self {
Either::Left((t, l)) => (t, Either::Left(l)),
Either::Right((t, r)) => (t, Either::Right(r)),
}
}
}
impl<T, L, R> Either<(L, T), (R, T)> {
pub fn factor_second(self) -> (T, Either<L, R>) {
match self {
Either::Left((l, t)) => (t, Either::Left(l)),
Either::Right((r, t)) => (t, Either::Right(r)),
}
}
}