icu_plurals/provider/rules/reference/
serializer.rs1use crate::provider::rules::reference::ast;
6use core::fmt;
7use core::ops::RangeInclusive;
8
9pub fn serialize(rule: &ast::Rule, w: &mut impl fmt::Write) -> fmt::Result {
39 serialize_condition(&rule.condition, w)?;
40 if let Some(samples) = &rule.samples {
41 serialize_samples(samples, w)?;
42 }
43 Ok(())
44}
45
46pub fn serialize_condition(cond: &ast::Condition, w: &mut impl fmt::Write) -> fmt::Result {
52 let mut first = true;
53
54 for cond in cond.0.iter() {
55 if first {
56 first = false;
57 } else {
58 w.write_str(" or ")?;
59 }
60 serialize_andcondition(cond, w)?;
61 }
62 Ok(())
63}
64
65fn serialize_andcondition(cond: &ast::AndCondition, w: &mut impl fmt::Write) -> fmt::Result {
66 let mut first = true;
67
68 for relation in cond.0.iter() {
69 if first {
70 first = false;
71 } else {
72 w.write_str(" and ")?;
73 }
74 serialize_relation(relation, w)?;
75 }
76 Ok(())
77}
78
79fn serialize_relation(relation: &ast::Relation, w: &mut impl fmt::Write) -> fmt::Result {
80 serialize_expression(&relation.expression, w)?;
81 w.write_char(' ')?;
82 serialize_operator(relation.operator, w)?;
83 w.write_char(' ')?;
84 serialize_rangelist(&relation.range_list, w)
85}
86
87fn serialize_expression(exp: &ast::Expression, w: &mut impl fmt::Write) -> fmt::Result {
88 serialize_operand(exp.operand, w)?;
89 if let Some(modulus) = &exp.modulus {
90 w.write_str(" % ")?;
91 serialize_value(modulus, w)?;
92 }
93 Ok(())
94}
95
96fn serialize_operator(operator: ast::Operator, w: &mut impl fmt::Write) -> fmt::Result {
97 match operator {
98 ast::Operator::Eq => w.write_char('='),
99 ast::Operator::NotEq => w.write_str("!="),
100 }
101}
102
103fn serialize_operand(operand: ast::Operand, w: &mut impl fmt::Write) -> fmt::Result {
104 match operand {
105 ast::Operand::N => w.write_char('n'),
106 ast::Operand::I => w.write_char('i'),
107 ast::Operand::V => w.write_char('v'),
108 ast::Operand::W => w.write_char('w'),
109 ast::Operand::F => w.write_char('f'),
110 ast::Operand::T => w.write_char('t'),
111 ast::Operand::C => w.write_char('c'),
112 ast::Operand::E => w.write_char('e'),
113 }
114}
115
116fn serialize_rangelist(rl: &ast::RangeList, w: &mut impl fmt::Write) -> fmt::Result {
117 let mut first = true;
118
119 for rli in rl.0.iter() {
120 if first {
121 first = false;
122 } else {
123 w.write_str(", ")?;
124 }
125 serialize_rangelistitem(rli, w)?
126 }
127 Ok(())
128}
129
130fn serialize_rangelistitem(rli: &ast::RangeListItem, w: &mut impl fmt::Write) -> fmt::Result {
131 match rli {
132 ast::RangeListItem::Range(range) => serialize_range(range, w),
133 ast::RangeListItem::Value(v) => serialize_value(v, w),
134 }
135}
136
137fn serialize_range(range: &RangeInclusive<ast::Value>, w: &mut impl fmt::Write) -> fmt::Result {
138 serialize_value(range.start(), w)?;
139 w.write_str("..")?;
140 serialize_value(range.end(), w)?;
141 Ok(())
142}
143
144fn serialize_value(value: &ast::Value, w: &mut impl fmt::Write) -> fmt::Result {
145 write!(w, "{}", value.0)
146}
147
148pub fn serialize_samples(samples: &ast::Samples, w: &mut impl fmt::Write) -> fmt::Result {
154 if let Some(sample_list) = &samples.integer {
155 w.write_str(" @integer ")?;
156 serialize_sample_list(sample_list, w)?;
157 }
158 if let Some(sample_list) = &samples.decimal {
159 w.write_str(" @decimal ")?;
160 serialize_sample_list(sample_list, w)?;
161 }
162 Ok(())
163}
164
165pub fn serialize_sample_list(samples: &ast::SampleList, w: &mut impl fmt::Write) -> fmt::Result {
171 let mut first = true;
172
173 for sample_range in samples.sample_ranges.iter() {
174 if first {
175 first = false;
176 } else {
177 w.write_str(", ")?;
178 }
179 serialize_sample_range(sample_range, w)?;
180 }
181
182 if samples.ellipsis {
183 w.write_str(", …")?;
184 }
185 Ok(())
186}
187
188pub fn serialize_sample_range(
194 sample_range: &ast::SampleRange,
195 w: &mut impl fmt::Write,
196) -> fmt::Result {
197 serialize_decimal_value(&sample_range.lower_val, w)?;
198 if let Some(upper_val) = &sample_range.upper_val {
199 w.write_char('~')?;
200 serialize_decimal_value(upper_val, w)?;
201 }
202 Ok(())
203}
204
205pub fn serialize_decimal_value(val: &ast::DecimalValue, w: &mut impl fmt::Write) -> fmt::Result {
211 w.write_str(&val.0)
212}