1
0
forked from M-Labs/nac3
nac3/nac3ast/src/fold_helpers.rs
2024-06-12 14:45:03 +08:00

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);