use crate::{
build::{Build, Builder},
walk::{Walk, WalkMut, WalkOnce},
};
#[derive(thiserror::Error, Debug)]
pub enum Either<A, B> {
#[error(transparent)]
A(A),
#[error(transparent)]
B(B),
}
pub fn from<'ctx, U, T>(
value: T,
) -> Result<U, Either<T::Error, <U::Builder as Builder<'ctx>>::Error>>
where
T: WalkOnce<'ctx>,
U: Build<'ctx>,
{
let mut builder = U::Builder::default();
value.walk_once(builder.as_visitor()).map_err(Either::A)?;
builder.build().map_err(Either::B)
}
pub fn from_mut<'a, 'ctx, U, T>(
value: &'a mut T,
) -> Result<U, Either<T::Error, <U::Builder as Builder<'ctx>>::Error>>
where
T: WalkMut<'a, 'ctx>,
U: Build<'ctx>,
{
let mut builder = U::Builder::default();
value.walk_mut(builder.as_visitor()).map_err(Either::A)?;
builder.build().map_err(Either::B)
}
pub fn from_ref<'a, 'ctx, U, T>(
value: &'a T,
) -> Result<U, Either<T::Error, <U::Builder as Builder<'ctx>>::Error>>
where
T: Walk<'a, 'ctx>,
U: Build<'ctx>,
{
let mut builder = U::Builder::default();
value.walk(builder.as_visitor()).map_err(Either::A)?;
builder.build().map_err(Either::B)
}