forked from M-Labs/nac3
68 lines
1.6 KiB
Rust
68 lines
1.6 KiB
Rust
use crate::constant;
|
|
use crate::fold::Fold;
|
|
use crate::StrRef;
|
|
|
|
pub(crate) trait Foldable<T, U> {
|
|
type Mapped;
|
|
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
|
|
self,
|
|
folder: &mut F,
|
|
) -> Result<Self::Mapped, F::Error>;
|
|
}
|
|
|
|
impl<T, U, X> Foldable<T, U> for Vec<X>
|
|
where
|
|
X: Foldable<T, U>,
|
|
{
|
|
type Mapped = Vec<X::Mapped>;
|
|
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
|
|
self,
|
|
folder: &mut F,
|
|
) -> Result<Self::Mapped, F::Error> {
|
|
self.into_iter().map(|x| x.fold(folder)).collect()
|
|
}
|
|
}
|
|
|
|
impl<T, U, X> Foldable<T, U> for Option<X>
|
|
where
|
|
X: Foldable<T, U>,
|
|
{
|
|
type Mapped = Option<X::Mapped>;
|
|
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
|
|
self,
|
|
folder: &mut F,
|
|
) -> Result<Self::Mapped, F::Error> {
|
|
self.map(|x| x.fold(folder)).transpose()
|
|
}
|
|
}
|
|
|
|
impl<T, U, X> Foldable<T, U> for Box<X>
|
|
where
|
|
X: Foldable<T, U>,
|
|
{
|
|
type Mapped = Box<X::Mapped>;
|
|
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
|
|
self,
|
|
folder: &mut F,
|
|
) -> Result<Self::Mapped, F::Error> {
|
|
(*self).fold(folder).map(Box::new)
|
|
}
|
|
}
|
|
|
|
macro_rules! simple_fold {
|
|
($($t:ty),+$(,)?) => {
|
|
$(impl<T, U> $crate::fold_helpers::Foldable<T, U> for $t {
|
|
type Mapped = Self;
|
|
#[inline]
|
|
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
|
|
self,
|
|
_folder: &mut F,
|
|
) -> Result<Self::Mapped, F::Error> {
|
|
Ok(self)
|
|
}
|
|
})+
|
|
};
|
|
}
|
|
|
|
simple_fold!(usize, String, bool, StrRef, constant::Constant, constant::ConversionFlag);
|