1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use std::f32;
use std::num::ParseFloatError;
use std::str::FromStr;
use intl_pluralrules::PluralCategory;
use super::bundle::FluentBundle;
#[derive(Clone, Debug, PartialEq)]
pub enum FluentValue {
String(String),
Number(String),
}
impl FluentValue {
pub fn as_number<S: ToString>(v: S) -> Result<Self, ParseFloatError> {
f64::from_str(&v.to_string()).map(|_| FluentValue::Number(v.to_string()))
}
pub fn format(&self, _bundle: &FluentBundle) -> String {
match self {
FluentValue::String(s) => s.clone(),
FluentValue::Number(n) => n.clone(),
}
}
pub fn matches(&self, bundle: &FluentBundle, other: &FluentValue) -> bool {
match (self, other) {
(&FluentValue::String(ref a), &FluentValue::String(ref b)) => a == b,
(&FluentValue::Number(ref a), &FluentValue::Number(ref b)) => a == b,
(&FluentValue::String(ref a), &FluentValue::Number(ref b)) => {
let cat = match a.as_str() {
"zero" => PluralCategory::ZERO,
"one" => PluralCategory::ONE,
"two" => PluralCategory::TWO,
"few" => PluralCategory::FEW,
"many" => PluralCategory::MANY,
"other" => PluralCategory::OTHER,
_ => return false,
};
let pr = &bundle.plural_rules;
pr.select(b.as_str()) == Ok(cat)
}
(&FluentValue::Number(..), &FluentValue::String(..)) => false,
}
}
}
impl From<String> for FluentValue {
fn from(s: String) -> Self {
FluentValue::String(s)
}
}
impl<'a> From<&'a str> for FluentValue {
fn from(s: &'a str) -> Self {
FluentValue::String(String::from(s))
}
}
impl From<f32> for FluentValue {
fn from(n: f32) -> Self {
FluentValue::Number(n.to_string())
}
}
impl From<isize> for FluentValue {
fn from(n: isize) -> Self {
FluentValue::Number(n.to_string())
}
}