fluent_static_codegen/
ast.rs

1use fluent_syntax::ast;
2
3pub trait Node<S> {
4    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output;
5}
6
7impl<S> Node<S> for ast::Resource<S> {
8    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output {
9        visitor.visit_resource(self)
10    }
11}
12
13impl<S> Node<S> for ast::Entry<S> {
14    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output {
15        visitor.visit_entry(self)
16    }
17}
18
19impl<S> Node<S> for ast::Message<S> {
20    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output {
21        visitor.visit_message(self)
22    }
23}
24
25impl<S> Node<S> for ast::Term<S> {
26    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output {
27        visitor.visit_term(self)
28    }
29}
30
31impl<S> Node<S> for ast::Pattern<S> {
32    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output {
33        visitor.visit_pattern(self)
34    }
35}
36
37impl<S> Node<S> for ast::PatternElement<S> {
38    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output {
39        match self {
40            ast::PatternElement::TextElement { value } => visitor.visit_text_element(value),
41            ast::PatternElement::Placeable { expression } => expression.accept(visitor),
42        }
43    }
44}
45
46impl<S> Node<S> for ast::Attribute<S> {
47    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output {
48        visitor.visit_attribute(self)
49    }
50}
51
52impl<S> Node<S> for ast::Variant<S> {
53    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output {
54        visitor.begin_variant(&self);
55        let result = visitor.visit_variant(&self.key, &self.value, self.default);
56        visitor.end_variant(&self);
57        result
58    }
59}
60
61impl<S> Node<S> for ast::Comment<S> {
62    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output {
63        visitor.visit_comment(self)
64    }
65}
66
67impl<S> Node<S> for ast::CallArguments<S> {
68    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output {
69        visitor.visit_call_arguments(self)
70    }
71}
72
73impl<S> Node<S> for ast::NamedArgument<S> {
74    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output {
75        visitor.visit_named_argument(self)
76    }
77}
78
79impl<S> Node<S> for ast::InlineExpression<S> {
80    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output {
81        visitor.begin_inline_expression(&self);
82        let result = match self {
83            ast::InlineExpression::StringLiteral { value } => visitor.visit_string_literal(value),
84            ast::InlineExpression::NumberLiteral { value } => visitor.visit_number_literal(value),
85            ast::InlineExpression::FunctionReference { id, arguments } => {
86                visitor.visit_function_reference(id, arguments)
87            }
88            ast::InlineExpression::MessageReference { id, attribute } => {
89                visitor.visit_message_reference(id, attribute.as_ref())
90            }
91            ast::InlineExpression::TermReference {
92                id,
93                attribute,
94                arguments,
95            } => visitor.visit_term_reference(id, attribute.as_ref(), arguments.as_ref()),
96            ast::InlineExpression::VariableReference { id } => visitor.visit_variable_reference(id),
97            ast::InlineExpression::Placeable { expression } => expression.accept(visitor),
98        };
99        visitor.end_inline_expression(&self);
100        result
101    }
102}
103
104impl<S> Node<S> for ast::Expression<S> {
105    fn accept<V: Visitor<S>>(&self, visitor: &mut V) -> V::Output {
106        match self {
107            ast::Expression::Select { selector, variants } => {
108                visitor.visit_select_expression(selector, variants.iter())
109            }
110            ast::Expression::Inline(expr) => expr.accept(visitor),
111        }
112    }
113}
114
115pub trait Visitor<S> {
116    type Output;
117
118    fn visit_resource(&mut self, resource: &ast::Resource<S>) -> Self::Output;
119    fn visit_entry(&mut self, entry: &ast::Entry<S>) -> Self::Output;
120    fn visit_message(&mut self, message: &ast::Message<S>) -> Self::Output;
121    fn visit_term(&mut self, term: &ast::Term<S>) -> Self::Output;
122    fn visit_pattern(&mut self, pattern: &ast::Pattern<S>) -> Self::Output;
123    fn visit_text_element(&mut self, value: &S) -> Self::Output;
124    fn visit_attribute(&mut self, attribute: &ast::Attribute<S>) -> Self::Output;
125
126    #[allow(unused_variables)]
127    fn begin_variant(&mut self, variant: &ast::Variant<S>) {}
128
129    fn visit_variant(
130        &mut self,
131        variant_key: &ast::VariantKey<S>,
132        pattern: &ast::Pattern<S>,
133        is_default: bool,
134    ) -> Self::Output;
135
136    #[allow(unused_variables)]
137    fn end_variant(&mut self, variant: &ast::Variant<S>) {}
138
139    fn visit_comment(&mut self, comment: &ast::Comment<S>) -> Self::Output;
140    fn visit_call_arguments(&mut self, arguments: &ast::CallArguments<S>) -> Self::Output;
141    fn visit_named_argument(&mut self, argument: &ast::NamedArgument<S>) -> Self::Output;
142
143    #[allow(unused_variables)]
144    fn begin_inline_expression(&mut self, inline_expression: &ast::InlineExpression<S>) {}
145
146    fn visit_string_literal(&mut self, value: &S) -> Self::Output;
147    fn visit_number_literal(&mut self, value: &S) -> Self::Output;
148    fn visit_function_reference(
149        &mut self,
150        id: &ast::Identifier<S>,
151        arguments: &ast::CallArguments<S>,
152    ) -> Self::Output;
153    fn visit_message_reference(
154        &mut self,
155        id: &ast::Identifier<S>,
156        attribute: Option<&ast::Identifier<S>>,
157    ) -> Self::Output;
158    fn visit_term_reference(
159        &mut self,
160        id: &ast::Identifier<S>,
161        attribute: Option<&ast::Identifier<S>>,
162        arguments: Option<&ast::CallArguments<S>>,
163    ) -> Self::Output;
164    fn visit_variable_reference(&mut self, id: &ast::Identifier<S>) -> Self::Output;
165
166    #[allow(unused_variables)]
167    fn end_inline_expression(&mut self, inline_expression: &ast::InlineExpression<S>) {}
168
169    #[allow(unused_variables)]
170    fn begin_expression(&mut self, expression: &ast::Expression<S>) {}
171    fn visit_select_expression<'a, I>(
172        &mut self,
173        selector: &'a ast::InlineExpression<S>,
174        variants: I,
175    ) -> Self::Output
176    where
177        I: Iterator<Item = &'a ast::Variant<S>>;
178
179    #[allow(unused_variables)]
180    fn end_expression(&mut self, expression: &ast::Expression<S>) {}
181}