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}