1use super::generic::*;
2
3use crate::{builtin, ConversionFlag};
4
5pub trait Foldable<T, U> {
6 type Mapped;
7 fn fold<F: Fold<T, TargetU = U> + ?Sized>(
8 self,
9 folder: &mut F,
10 ) -> Result<Self::Mapped, F::Error>;
11}
12
13impl<T, U, X> Foldable<T, U> for Vec<X>
14where
15 X: Foldable<T, U>,
16{
17 type Mapped = Vec<X::Mapped>;
18 fn fold<F: Fold<T, TargetU = U> + ?Sized>(
19 self,
20 folder: &mut F,
21 ) -> Result<Self::Mapped, F::Error> {
22 self.into_iter().map(|x| x.fold(folder)).collect()
23 }
24}
25
26impl<T, U, X> Foldable<T, U> for Option<X>
27where
28 X: Foldable<T, U>,
29{
30 type Mapped = Option<X::Mapped>;
31 fn fold<F: Fold<T, TargetU = U> + ?Sized>(
32 self,
33 folder: &mut F,
34 ) -> Result<Self::Mapped, F::Error> {
35 self.map(|x| x.fold(folder)).transpose()
36 }
37}
38
39impl<T, U, X> Foldable<T, U> for Box<X>
40where
41 X: Foldable<T, U>,
42{
43 type Mapped = Box<X::Mapped>;
44 fn fold<F: Fold<T, TargetU = U> + ?Sized>(
45 self,
46 folder: &mut F,
47 ) -> Result<Self::Mapped, F::Error> {
48 (*self).fold(folder).map(Box::new)
49 }
50}
51
52macro_rules! simple_fold {
53 ($($t:ty),+$(,)?) => {
54 $(impl<T, U> $crate::fold::Foldable<T, U> for $t {
55 type Mapped = Self;
56 #[inline]
57 fn fold<F: Fold<T, TargetU = U> + ?Sized>(
58 self,
59 _folder: &mut F,
60 ) -> Result<Self::Mapped, F::Error> {
61 Ok(self)
62 }
63 })+
64 };
65}
66
67simple_fold!(
68 builtin::Int,
69 builtin::String,
70 builtin::Identifier,
71 bool,
72 ConversionFlag,
73 builtin::Constant
74);
75
76include!("gen/fold.rs");