1 | use super::scope::Scope; |
2 | use super::WriteValue; |
3 | |
4 | use std::borrow::Borrow; |
5 | use std::fmt; |
6 | |
7 | use fluent_syntax::ast; |
8 | |
9 | use crate::memoizer::MemoizerKind; |
10 | use crate::resolver::{ResolveValue, ResolverError}; |
11 | use crate::resource::FluentResource; |
12 | use crate::types::FluentValue; |
13 | |
14 | impl<'p> WriteValue for ast::Expression<&'p str> { |
15 | fn write<'scope, 'errors, W, R, M>( |
16 | &'scope self, |
17 | w: &mut W, |
18 | scope: &mut Scope<'scope, 'errors, R, M>, |
19 | ) -> fmt::Result |
20 | where |
21 | W: fmt::Write, |
22 | R: Borrow<FluentResource>, |
23 | M: MemoizerKind, |
24 | { |
25 | match self { |
26 | Self::Inline(exp) => exp.write(w, scope), |
27 | Self::Select { selector, variants } => { |
28 | let selector = selector.resolve(scope); |
29 | match selector { |
30 | FluentValue::String(_) | FluentValue::Number(_) => { |
31 | for variant in variants { |
32 | let key = match variant.key { |
33 | ast::VariantKey::Identifier { name } => name.into(), |
34 | ast::VariantKey::NumberLiteral { value } => { |
35 | FluentValue::try_number(value) |
36 | } |
37 | }; |
38 | if key.matches(&selector, scope) { |
39 | return variant.value.write(w, scope); |
40 | } |
41 | } |
42 | } |
43 | _ => {} |
44 | } |
45 | |
46 | for variant in variants { |
47 | if variant.default { |
48 | return variant.value.write(w, scope); |
49 | } |
50 | } |
51 | scope.add_error(ResolverError::MissingDefault); |
52 | Ok(()) |
53 | } |
54 | } |
55 | } |
56 | |
57 | fn write_error<W>(&self, w: &mut W) -> fmt::Result |
58 | where |
59 | W: fmt::Write, |
60 | { |
61 | match self { |
62 | Self::Inline(exp) => exp.write_error(w), |
63 | Self::Select { .. } => unreachable!(), |
64 | } |
65 | } |
66 | } |
67 | |