fluent_static_codegen/
ast.rs1use 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}