sails_idl_parser/ast/
visitor.rs

1use super::*;
2
3pub trait Visitor<'ast> {
4    fn visit_ctor(&mut self, ctor: &'ast Ctor) {
5        accept_ctor(ctor, self);
6    }
7
8    fn visit_service(&mut self, service: &'ast Service) {
9        accept_service(service, self);
10    }
11
12    fn visit_type(&mut self, r#type: &'ast Type) {
13        accept_type(r#type, self);
14    }
15
16    fn visit_vector_type_decl(&mut self, item_type_decl: &'ast TypeDecl) {
17        accept_type_decl(item_type_decl, self);
18    }
19
20    fn visit_array_type_decl(&mut self, item_type_decl: &'ast TypeDecl, _len: u32) {
21        accept_type_decl(item_type_decl, self);
22    }
23
24    fn visit_map_type_decl(
25        &mut self,
26        key_type_decl: &'ast TypeDecl,
27        value_type_decl: &'ast TypeDecl,
28    ) {
29        accept_type_decl(key_type_decl, self);
30        accept_type_decl(value_type_decl, self);
31    }
32
33    fn visit_optional_type_decl(&mut self, optional_type_decl: &'ast TypeDecl) {
34        accept_type_decl(optional_type_decl, self);
35    }
36
37    fn visit_result_type_decl(
38        &mut self,
39        ok_type_decl: &'ast TypeDecl,
40        err_type_decl: &'ast TypeDecl,
41    ) {
42        accept_type_decl(ok_type_decl, self);
43        accept_type_decl(err_type_decl, self);
44    }
45
46    fn visit_primitive_type_id(&mut self, _primitive_type_id: PrimitiveType) {}
47
48    fn visit_user_defined_type_id(&mut self, _user_defined_type_id: &'ast str) {}
49
50    fn visit_ctor_func(&mut self, func: &'ast CtorFunc) {
51        accept_ctor_func(func, self);
52    }
53
54    fn visit_service_func(&mut self, func: &'ast ServiceFunc) {
55        accept_service_func(func, self);
56    }
57
58    fn visit_service_event(&mut self, event: &'ast ServiceEvent) {
59        accept_service_event(event, self);
60    }
61
62    fn visit_func_param(&mut self, func_param: &'ast FuncParam) {
63        accept_func_param(func_param, self);
64    }
65
66    fn visit_func_output(&mut self, func_output: &'ast TypeDecl) {
67        accept_type_decl(func_output, self);
68    }
69
70    fn visit_struct_def(&mut self, struct_def: &'ast StructDef) {
71        accept_struct_def(struct_def, self);
72    }
73
74    fn visit_struct_field(&mut self, struct_field: &'ast StructField) {
75        accept_struct_field(struct_field, self);
76    }
77
78    fn visit_enum_def(&mut self, enum_def: &'ast EnumDef) {
79        accept_enum_def(enum_def, self);
80    }
81
82    fn visit_enum_variant(&mut self, enum_variant: &'ast EnumVariant) {
83        accept_enum_variant(enum_variant, self);
84    }
85}
86
87pub fn accept_program<'ast>(program: &'ast Program, visitor: &mut (impl Visitor<'ast> + ?Sized)) {
88    if let Some(ctor) = program.ctor() {
89        visitor.visit_ctor(ctor);
90    }
91    for service in program.services() {
92        visitor.visit_service(service);
93    }
94    for r#type in program.types() {
95        visitor.visit_type(r#type);
96    }
97}
98
99pub fn accept_ctor<'ast>(ctor: &'ast Ctor, visitor: &mut (impl Visitor<'ast> + ?Sized)) {
100    for func in ctor.funcs() {
101        visitor.visit_ctor_func(func);
102    }
103}
104
105pub fn accept_ctor_func<'ast>(func: &'ast CtorFunc, visitor: &mut (impl Visitor<'ast> + ?Sized)) {
106    for param in func.params() {
107        visitor.visit_func_param(param);
108    }
109}
110
111pub fn accept_service<'ast>(service: &'ast Service, visitor: &mut (impl Visitor<'ast> + ?Sized)) {
112    for func in service.funcs() {
113        visitor.visit_service_func(func);
114    }
115    for event in service.events() {
116        visitor.visit_service_event(event);
117    }
118}
119
120pub fn accept_service_func<'ast>(
121    func: &'ast ServiceFunc,
122    visitor: &mut (impl Visitor<'ast> + ?Sized),
123) {
124    for param in func.params() {
125        visitor.visit_func_param(param);
126    }
127    visitor.visit_func_output(func.output());
128}
129
130pub fn accept_service_event<'ast>(
131    event: &'ast ServiceEvent,
132    visitor: &mut (impl Visitor<'ast> + ?Sized),
133) {
134    accept_enum_variant(event, visitor)
135}
136
137pub fn accept_func_param<'ast>(
138    func_param: &'ast FuncParam,
139    visitor: &mut (impl Visitor<'ast> + ?Sized),
140) {
141    accept_type_decl(func_param.type_decl(), visitor);
142}
143
144pub fn accept_type<'ast>(r#type: &'ast Type, visitor: &mut (impl Visitor<'ast> + ?Sized)) {
145    accept_type_def(r#type.def(), visitor);
146}
147
148pub fn accept_type_decl<'ast>(
149    type_decl: &'ast TypeDecl,
150    visitor: &mut (impl Visitor<'ast> + ?Sized),
151) {
152    match type_decl {
153        TypeDecl::Vector(item_type_decl) => {
154            visitor.visit_vector_type_decl(item_type_decl);
155        }
156        TypeDecl::Array { item, len } => {
157            visitor.visit_array_type_decl(item, *len);
158        }
159        TypeDecl::Map { key, value } => {
160            visitor.visit_map_type_decl(key, value);
161        }
162        TypeDecl::Optional(optional_type_decl) => {
163            visitor.visit_optional_type_decl(optional_type_decl);
164        }
165        TypeDecl::Result { ok, err } => {
166            visitor.visit_result_type_decl(ok, err);
167        }
168        TypeDecl::Id(TypeId::Primitive(primitive_type_id)) => {
169            visitor.visit_primitive_type_id(*primitive_type_id);
170        }
171        TypeDecl::Id(TypeId::UserDefined(user_defined_type_id)) => {
172            visitor.visit_user_defined_type_id(user_defined_type_id);
173        }
174        TypeDecl::Def(type_def) => {
175            accept_type_def(type_def, visitor);
176        }
177    }
178}
179
180pub fn accept_type_def<'ast>(type_def: &'ast TypeDef, visitor: &mut (impl Visitor<'ast> + ?Sized)) {
181    match type_def {
182        TypeDef::Struct(struct_def) => {
183            visitor.visit_struct_def(struct_def);
184        }
185        TypeDef::Enum(enum_def) => {
186            visitor.visit_enum_def(enum_def);
187        }
188    }
189}
190
191pub fn accept_struct_def<'ast>(
192    struct_def: &'ast StructDef,
193    visitor: &mut (impl Visitor<'ast> + ?Sized),
194) {
195    for field in struct_def.fields() {
196        visitor.visit_struct_field(field);
197    }
198}
199
200pub fn accept_struct_field<'ast>(
201    struct_field: &'ast StructField,
202    visitor: &mut (impl Visitor<'ast> + ?Sized),
203) {
204    accept_type_decl(struct_field.type_decl(), visitor);
205}
206
207pub fn accept_enum_def<'ast>(enum_def: &'ast EnumDef, visitor: &mut (impl Visitor<'ast> + ?Sized)) {
208    for variant in enum_def.variants() {
209        visitor.visit_enum_variant(variant);
210    }
211}
212
213pub fn accept_enum_variant<'ast>(
214    enum_variant: &'ast EnumVariant,
215    visitor: &mut (impl Visitor<'ast> + ?Sized),
216) {
217    if let Some(type_decl) = enum_variant.type_decl().as_ref() {
218        accept_type_decl(type_decl, visitor);
219    }
220}
221
222#[cfg(test)]
223mod tests {
224    use super::*;
225
226    struct ProgramVisitor<'ast> {
227        services: Vec<&'ast Service>,
228        types: Vec<&'ast Type>,
229    }
230
231    impl<'ast> Visitor<'ast> for ProgramVisitor<'ast> {
232        fn visit_service(&mut self, service: &'ast Service) {
233            self.services.push(service);
234        }
235
236        fn visit_type(&mut self, r#type: &'ast Type) {
237            self.types.push(r#type);
238        }
239    }
240
241    #[test]
242    fn accept_program_works() {
243        let program = Program::new(
244            Some(Ctor::new(vec![]).unwrap()),
245            vec![Service::new(String::default(), vec![], vec![]).unwrap()],
246            vec![
247                Type::new(
248                    "Type1".into(),
249                    TypeDef::Struct(StructDef::new(vec![]).unwrap()),
250                    vec![],
251                ),
252                Type::new(
253                    "Type2".into(),
254                    TypeDef::Enum(EnumDef::new(vec![]).unwrap()),
255                    vec![],
256                ),
257            ],
258        )
259        .unwrap();
260        let mut program_visitor = ProgramVisitor {
261            services: vec![],
262            types: vec![],
263        };
264
265        accept_program(&program, &mut program_visitor);
266
267        assert!(itertools::equal(
268            program_visitor.services,
269            program.services()
270        ));
271        assert!(itertools::equal(program_visitor.types, program.types()));
272    }
273
274    struct EnumDefVisitor<'ast> {
275        variants: Vec<&'ast EnumVariant>,
276    }
277
278    impl<'ast> Visitor<'ast> for EnumDefVisitor<'ast> {
279        fn visit_enum_variant(&mut self, enum_variant: &'ast EnumVariant) {
280            self.variants.push(enum_variant);
281        }
282    }
283
284    #[test]
285    fn accept_enum_def_works() {
286        let enum_def = EnumDef::new(vec![
287            EnumVariant::new("Variant1".into(), None, vec![]),
288            EnumVariant::new(
289                "Variant2".into(),
290                Some(TypeDecl::Id(TypeId::Primitive(PrimitiveType::U32))),
291                vec![],
292            ),
293        ])
294        .unwrap();
295        let mut enum_def_visitor = EnumDefVisitor { variants: vec![] };
296
297        accept_enum_def(&enum_def, &mut enum_def_visitor);
298
299        assert!(itertools::equal(
300            enum_def_visitor.variants,
301            enum_def.variants()
302        ));
303    }
304}