cldr_pluralrules_parser/ast.rs
1#[derive(Debug, Clone, PartialEq)]
2pub struct Rule {
3 pub condition: Condition,
4 pub samples: Option<Samples>,
5}
6
7#[derive(Debug, Clone, PartialEq)]
8pub struct Samples {
9 pub integer: Option<SampleList>,
10 pub decimal: Option<SampleList>,
11}
12
13#[derive(Debug, Clone, PartialEq)]
14pub struct SampleList {
15 pub sample_ranges: Vec<SampleRange>,
16 pub ellipsis: bool,
17}
18
19#[derive(Debug, Clone, PartialEq)]
20pub struct SampleRange {
21 pub lower_val: DecimalValue,
22 pub upper_val: Option<DecimalValue>,
23}
24
25#[derive(Debug, Clone, PartialEq)]
26pub struct DecimalValue {
27 pub integer: Value,
28 pub decimal: Option<Value>,
29}
30
31/// A complete (and the only complete) AST representation of a plural rule. Comprises a vector of AndConditions.
32///
33/// # Examples
34///
35/// All AST nodes can be built explicitly, as seen in the example. However, due to its complexity, it is preferred to build the AST using the parse_plural_rule function.
36///
37/// ```text
38/// "i = 5"
39/// ```
40///
41/// Can be represented by the AST:
42///
43/// ```
44/// use cldr_pluralrules_parser::ast::*;
45///
46/// Condition(vec![AndCondition(vec![Relation {
47/// expression: Expression {
48/// operand: Operand::I,
49/// modulus: None,
50/// },
51/// operator: Operator::EQ,
52/// range_list: RangeList(vec![RangeListItem::Value(Value(5))]),
53/// }])]);
54/// ```
55///
56/// Because they care complete representations, hand-written Conditions can be verified with the assert macro. No other AST nodes can be verified.
57///
58/// ```
59/// use cldr_pluralrules_parser::ast::*;
60/// use cldr_pluralrules_parser::parse_plural_rule;
61///
62/// let condition = Condition(vec![
63/// AndCondition(vec![Relation {
64/// expression: Expression {
65/// operand: Operand::I,
66/// modulus: None,
67/// },
68/// operator: Operator::Is,
69/// range_list: RangeList(vec![RangeListItem::Value(Value(5))]),
70/// }]),
71/// AndCondition(vec![Relation {
72/// expression: Expression {
73/// operand: Operand::V,
74/// modulus: None,
75/// },
76/// operator: Operator::Within,
77/// range_list: RangeList(vec![RangeListItem::Value(Value(2))]),
78/// }]),
79/// ]);
80///
81/// assert_eq!(
82/// condition,
83/// parse_plural_rule("i is 5 or v within 2")
84/// .expect("Parsing succeeded")
85/// .condition
86/// )
87/// ```
88#[derive(Debug, Clone, PartialEq)]
89pub struct Condition(pub Vec<AndCondition>);
90
91/// An incomplete AST representation of a plural rule. Comprises a vector of Relations.
92///
93/// # Examples
94///
95/// All AST nodes can be built explicitly, as seen in the example. However, due to its complexity, it is preferred to build the AST using the parse_plural_rule function.
96///
97/// ```text
98/// "i = 3 and v = 0"
99/// ```
100///
101/// Can be represented by the AST:
102///
103/// ```
104/// use cldr_pluralrules_parser::ast::*;
105///
106/// AndCondition(vec![
107/// Relation {
108/// expression: Expression {
109/// operand: Operand::I,
110/// modulus: None,
111/// },
112/// operator: Operator::In,
113/// range_list: RangeList(vec![RangeListItem::Value(Value(5))]),
114/// },
115/// Relation {
116/// expression: Expression {
117/// operand: Operand::V,
118/// modulus: None,
119/// },
120/// operator: Operator::NotIn,
121/// range_list: RangeList(vec![RangeListItem::Value(Value(2))]),
122/// },
123/// ]);
124///
125/// ```
126#[derive(Debug, Clone, PartialEq)]
127pub struct AndCondition(pub Vec<Relation>);
128
129/// An incomplete AST representation of a plural rule. Comprises an Expression, an Operator, and a RangeList.
130///
131/// # Examples
132///
133/// All AST nodes can be built explicitly, as seen in the example. However, due to its complexity, it is preferred to build the AST using the parse_plural_rule function.
134///
135/// ```text
136/// "i = 3"
137/// ```
138///
139/// Can be represented by the AST:
140///
141/// ```
142/// use cldr_pluralrules_parser::ast::*;
143///
144/// Relation {
145/// expression: Expression {
146/// operand: Operand::I,
147/// modulus: None,
148/// },
149/// operator: Operator::Is,
150/// range_list: RangeList(vec![RangeListItem::Value(Value(3))]),
151/// };
152///
153/// ```
154#[derive(Debug, Clone, PartialEq)]
155pub struct Relation {
156 pub expression: Expression,
157 pub operator: Operator,
158 pub range_list: RangeList,
159}
160
161/// An enum of Relation operators for plural rules.
162///
163/// Each Operator enumeration belongs to the corresponding symbolic operators:
164///
165/// | Enum Operator | Symbolic Operator |
166/// | - | - |
167/// | In | "in" |
168/// | NotIn | "not in" |
169/// | Within | "within" |
170/// | NotWithin | "not within" |
171/// | Is | "is" |
172/// | IsNot | "is not" |
173/// | EQ | "=" |
174/// | NotEq | "!=" |
175///
176#[derive(Debug, Clone, PartialEq)]
177pub enum Operator {
178 In,
179 NotIn,
180 Within,
181 NotWithin,
182 Is,
183 IsNot,
184 EQ,
185 NotEQ,
186}
187
188/// An incomplete AST representation of a plural rule. Comprises an Operand and an optional Modulo.
189///
190/// # Examples
191///
192/// All AST nodes can be built explicitly, as seen in the example. However, due to its complexity, it is preferred to build the AST using the parse_plural_rule function.
193///
194/// ```text
195/// "i % 100"
196/// ```
197///
198/// Can be represented by the AST:
199///
200/// ```
201/// use cldr_pluralrules_parser::ast::*;
202///
203/// Expression {
204/// operand: Operand::I,
205/// modulus: Some(Modulo(Value(100))),
206/// };
207///
208/// ```
209#[derive(Debug, Clone, PartialEq)]
210pub struct Expression {
211 pub operand: Operand,
212 pub modulus: Option<Modulo>,
213}
214
215/// An incomplete AST representation of a plural rule. Comprises a Value but is later expressed as `% usize`.
216///
217/// # Examples
218///
219/// All AST nodes can be built explicitly, as seen in the example. However, due to its complexity, it is preferred to build the AST using the parse_plural_rule function.
220///
221/// ```text
222/// "% 100"
223/// ```
224///
225/// Will be used to represent the AST:
226///
227/// ```
228/// use cldr_pluralrules_parser::ast::*;
229///
230/// Modulo(Value(100));
231/// ```
232#[derive(Debug, Clone, PartialEq)]
233pub struct Modulo(pub Value);
234
235/// An incomplete AST representation of a plural rule. Comprises a char.
236///
237/// # Examples
238///
239/// All AST nodes can be built explicitly, as seen in the example. However, due to its complexity, it is preferred to build the AST using the parse_plural_rule function.
240///
241/// ```text
242/// "i"
243/// ```
244///
245/// Can be represented by the AST:
246///
247/// ```
248/// use cldr_pluralrules_parser::ast::Operand;
249///
250/// Operand::I;
251/// ```
252#[derive(Debug, Clone, PartialEq)]
253pub enum Operand {
254 N, // Absolute value of input
255 I, // Integer value of input
256 V, // Number of visible fraction digits with trailing zeros
257 W, // Number of visible fraction digits without trailing zeros
258 F, // Visible fraction digits with trailing zeros
259 T, // Visible fraction digits without trailing zeros
260}
261
262/// An incomplete AST representation of a plural rule. Comprises a vector of RangeListItems.
263///
264/// # Examples
265///
266/// All AST nodes can be built explicitly, as seen in the example. However, due to its complexity, it is preferred to build the AST using the parse_plural_rule function.
267///
268/// ```text
269/// "5, 7, 9"
270/// ```
271///
272/// Can be represented by the AST:
273///
274/// ```
275/// use cldr_pluralrules_parser::ast::*;
276///
277/// RangeList(vec![
278/// RangeListItem::Value(Value(5)),
279/// RangeListItem::Value(Value(7)),
280/// RangeListItem::Value(Value(9)),
281/// ]);
282/// ```
283#[derive(Debug, Clone, PartialEq)]
284pub struct RangeList(pub Vec<RangeListItem>);
285
286/// An enum of items that appear in a RangeList: Range or a Value.
287///
288/// See Range and Value for additional details.
289///
290#[derive(Debug, Clone, PartialEq)]
291pub enum RangeListItem {
292 Range(Range),
293 Value(Value),
294}
295
296/// An incomplete AST representation of a plural rule. Comprises two Values: an inclusive lower and upper limit.
297///
298/// # Examples
299///
300/// All AST nodes can be built explicitly, as seen in the example. However, due to its complexity, it is preferred to build the AST using the parse_plural_rule function.
301///
302/// ```text
303/// "11..15"
304/// ```
305///
306/// Can be represented by the AST:
307///
308/// ```
309/// use cldr_pluralrules_parser::ast::*;
310///
311/// RangeListItem::Range(Range {
312/// lower_val: Value(11),
313/// upper_val: Value(15),
314/// });
315/// ```
316#[derive(Debug, Clone, PartialEq)]
317pub struct Range {
318 pub lower_val: Value,
319 pub upper_val: Value,
320}
321
322/// An incomplete AST representation of a plural rule, representing one integer.
323///
324/// # Examples
325///
326/// All AST nodes can be built explicitly, as seen in the example. However, due to its complexity, it is preferred to build the AST using the parse_plural_rule function.
327///
328/// ```text
329/// "99"
330/// ```
331///
332/// Can be represented by the AST:
333///
334/// ```
335/// use cldr_pluralrules_parser::ast::*;
336///
337/// RangeListItem::Value(Value(99));
338/// ```
339#[derive(Debug, Clone, PartialEq)]
340pub struct Value(pub usize);