rustpython_ast/
fold.rs

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