fluent_testing/scenarios/
structs.rs1use fluent_fallback::types::ResourceId;
2
3pub struct FileSource {
4 pub name: String,
5 pub locales: Vec<String>,
6 pub path_scheme: String,
7}
8
9impl Default for FileSource {
10 fn default() -> Self {
11 Self {
12 name: "default".to_string(),
13 path_scheme: "{locale}/".to_string(),
14 locales: vec!["en-US".to_string()],
15 }
16 }
17}
18
19impl FileSource {
20 pub fn new<S: ToString>(name: S, path_scheme: S, locales: Vec<S>) -> Self {
21 Self {
22 name: name.to_string(),
23 path_scheme: path_scheme.to_string(),
24 locales: locales
25 .iter()
26 .map(|l| l.to_string().parse().unwrap())
27 .collect(),
28 }
29 }
30}
31
32#[derive(Debug)]
33pub struct L10nAttribute {
34 pub name: String,
35 pub value: String,
36}
37
38impl L10nAttribute {
39 pub fn new<S: ToString>(name: S, value: S) -> Self {
40 Self {
41 name: name.to_string(),
42 value: value.to_string(),
43 }
44 }
45}
46
47#[derive(Debug)]
48pub struct L10nMessage {
49 pub value: Option<String>,
50 pub attributes: Option<Vec<L10nAttribute>>,
51}
52
53impl L10nMessage {
54 pub fn new(value: Option<&str>, attributes: Option<Vec<L10nAttribute>>) -> Self {
55 Self {
56 value: value.map(|v| v.to_string()),
57 attributes,
58 }
59 }
60}
61
62impl From<&str> for L10nMessage {
63 fn from(value: &str) -> Self {
64 Self {
65 value: Some(value.to_string()),
66 attributes: None,
67 }
68 }
69}
70
71#[derive(Debug)]
72pub struct L10nArgument {
73 pub id: String,
74 pub value: String,
75}
76
77impl L10nArgument {
78 pub fn new<S: ToString>(id: S, value: S) -> Self {
79 Self {
80 id: id.to_string(),
81 value: value.to_string(),
82 }
83 }
84}
85
86#[derive(Debug)]
87pub struct L10nKey {
88 pub id: String,
89 pub args: Option<Vec<L10nArgument>>,
90}
91
92impl L10nKey {
93 pub fn new<S: ToString>(id: S, args: Option<Vec<L10nArgument>>) -> Self {
94 Self {
95 id: id.to_string(),
96 args,
97 }
98 }
99}
100
101impl From<&str> for L10nKey {
102 fn from(input: &str) -> Self {
103 Self {
104 id: input.to_string(),
105 args: None,
106 }
107 }
108}
109
110#[derive(Clone, Copy, Debug)]
111pub enum ExceptionalContext {
112 None,
114 ValueMissingFromResource,
116 ValueMissingFromAllResources,
118 OptionalResourceMissingFromLocale,
120 OptionalResourceMissingFromAllLocales,
122 RequiredResourceMissingFromLocale,
124 RequiredResourceMissingFromAllLocales,
126}
127
128impl ExceptionalContext {
129 pub fn missing_required_resource(self) -> bool {
131 matches!(
132 self,
133 Self::RequiredResourceMissingFromLocale | Self::RequiredResourceMissingFromAllLocales,
134 )
135 }
136
137 pub fn causes_reported_format_error(self) -> bool {
139 matches!(
140 self,
141 Self::ValueMissingFromResource
142 | Self::ValueMissingFromAllResources
143 | Self::OptionalResourceMissingFromLocale
144 | Self::OptionalResourceMissingFromAllLocales
145 | Self::RequiredResourceMissingFromAllLocales,
146 )
147 }
148
149 pub fn causes_failed_value_lookup(self) -> bool {
151 matches!(
152 self,
153 Self::ValueMissingFromAllResources
154 | Self::OptionalResourceMissingFromAllLocales
155 | Self::RequiredResourceMissingFromAllLocales,
156 )
157 }
158
159 pub fn blocks_bundle_generation(self) -> bool {
161 matches!(self, Self::RequiredResourceMissingFromAllLocales,)
162 }
163}
164
165#[derive(Debug)]
166pub struct Query {
167 pub input: L10nKey,
168 pub output: Option<L10nMessage>,
169 pub exceptional_context: ExceptionalContext,
170}
171
172impl Query {
173 pub fn new<K: Into<L10nKey>>(input: K, output: Option<L10nMessage>) -> Self {
174 Self {
175 input: input.into(),
176 output,
177 exceptional_context: ExceptionalContext::None,
178 }
179 }
180}
181
182impl From<(&str, &str)> for Query {
183 fn from(i: (&str, &str)) -> Self {
184 Self {
185 input: i.0.into(),
186 output: Some(i.1.into()),
187 exceptional_context: ExceptionalContext::None,
188 }
189 }
190}
191
192impl From<(&str, &str, ExceptionalContext)> for Query {
193 fn from(i: (&str, &str, ExceptionalContext)) -> Self {
194 Self {
195 input: i.0.into(),
196 output: Some(i.1.into()),
197 exceptional_context: i.2,
198 }
199 }
200}
201
202impl From<(&str, L10nMessage)> for Query {
203 fn from(i: (&str, L10nMessage)) -> Self {
204 Self {
205 input: i.0.into(),
206 output: Some(i.1),
207 exceptional_context: ExceptionalContext::None,
208 }
209 }
210}
211
212impl From<(L10nKey, L10nMessage)> for Query {
213 fn from(i: (L10nKey, L10nMessage)) -> Self {
214 Self {
215 input: i.0,
216 output: Some(i.1),
217 exceptional_context: ExceptionalContext::None,
218 }
219 }
220}
221
222impl From<&str> for Query {
223 fn from(i: &str) -> Self {
224 Self {
225 input: i.into(),
226 output: None,
227 exceptional_context: ExceptionalContext::None,
228 }
229 }
230}
231
232impl From<L10nKey> for Query {
233 fn from(key: L10nKey) -> Self {
234 Self {
235 input: key,
236 output: None,
237 exceptional_context: ExceptionalContext::None,
238 }
239 }
240}
241
242pub struct Queries(pub Vec<Query>);
243
244impl From<Vec<&str>> for Queries {
245 fn from(input: Vec<&str>) -> Self {
246 Self(input.into_iter().map(|q| q.into()).collect())
247 }
248}
249
250impl From<Vec<(&str, &str)>> for Queries {
251 fn from(input: Vec<(&str, &str)>) -> Self {
252 Self(input.into_iter().map(|q| q.into()).collect())
253 }
254}
255
256impl std::ops::Deref for Queries {
257 type Target = Vec<Query>;
258
259 fn deref(&self) -> &Self::Target {
260 &self.0
261 }
262}
263
264pub struct Scenario {
265 pub name: String,
266 pub file_sources: Vec<FileSource>,
267 pub locales: Vec<String>,
268 pub res_ids: Vec<ResourceId>,
269 pub queries: Queries,
270}
271
272impl Scenario {
273 pub fn new<S: ToString, R: Into<ResourceId>, Q: Into<Queries>>(
274 name: S,
275 file_sources: Vec<FileSource>,
276 locales: Vec<S>,
277 res_ids: Vec<R>,
278 queries: Q,
279 ) -> Self {
280 Self {
281 name: name.to_string(),
282 file_sources,
283 locales: locales
284 .into_iter()
285 .map(|l| l.to_string().parse().unwrap())
286 .collect(),
287 res_ids: res_ids.into_iter().map(|id| id.into()).collect(),
288 queries: queries.into(),
289 }
290 }
291}