ravenrs_app_a11y/
words.rs1pub const KEYS: &[&str] =
9 &["a11y.saved", "a11y.not_saved", "a11y.deleted_one", "a11y.deleted_many", "a11y.showing"];
10
11#[derive(Clone, Debug, PartialEq, Eq)]
13#[non_exhaustive]
14pub struct AccessWords {
15 pub saved: String,
17 pub not_saved: String,
19 pub deleted_one: String,
21 pub deleted_many: String,
23 pub showing: String,
25}
26
27impl Default for AccessWords {
28 fn default() -> Self {
29 Self::english()
30 }
31}
32
33impl AccessWords {
34 pub fn english() -> Self {
36 Self {
37 saved: "Saved: {0}".into(),
38 not_saved: "Not saved. {0}".into(),
39 deleted_one: "1 record deleted".into(),
40 deleted_many: "{0} records deleted".into(),
41 showing: "Showing {0}".into(),
42 }
43 }
44
45 pub fn pt_br() -> Self {
47 Self {
48 saved: "Salvo: {0}".into(),
49 not_saved: "Não foi salvo. {0}".into(),
50 deleted_one: "1 registro apagado".into(),
51 deleted_many: "{0} registros apagados".into(),
52 showing: "Mostrando {0}".into(),
53 }
54 }
55
56 pub fn for_language(code: &str) -> Self {
58 let code = code.trim().replace('_', "-").to_ascii_lowercase();
59 if code == "pt" || code.starts_with("pt-") { Self::pt_br() } else { Self::english() }
60 }
61
62 pub fn from_lookup(self, lookup: impl Fn(&str) -> Option<String>) -> Self {
65 let take = |key: &str, kept: String| lookup(key).unwrap_or(kept);
66 Self {
67 saved: take("a11y.saved", self.saved),
68 not_saved: take("a11y.not_saved", self.not_saved),
69 deleted_one: take("a11y.deleted_one", self.deleted_one),
70 deleted_many: take("a11y.deleted_many", self.deleted_many),
71 showing: take("a11y.showing", self.showing),
72 }
73 }
74
75 pub fn get(&self, key: &str) -> Option<&str> {
77 Some(match key {
78 "a11y.saved" => &self.saved,
79 "a11y.not_saved" => &self.not_saved,
80 "a11y.deleted_one" => &self.deleted_one,
81 "a11y.deleted_many" => &self.deleted_many,
82 "a11y.showing" => &self.showing,
83 _ => return None,
84 })
85 }
86
87 pub fn saved(&self, name: &str) -> String {
89 self.saved.replace("{0}", name)
90 }
91
92 pub fn not_saved(&self, why: &str) -> String {
94 self.not_saved.replace("{0}", why).trim().to_owned()
95 }
96
97 pub fn deleted(&self, count: usize) -> String {
99 if count == 1 {
100 self.deleted_one.clone()
101 } else {
102 self.deleted_many.replace("{0}", &count.to_string())
103 }
104 }
105
106 pub fn showing(&self, title: &str) -> String {
108 self.showing.replace("{0}", title)
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115
116 #[test]
117 fn every_key_has_words_in_each_language() {
118 for words in [AccessWords::english(), AccessWords::pt_br()] {
119 for key in KEYS {
120 assert!(words.get(key).is_some_and(|text| !text.is_empty()), "{key}");
121 }
122 }
123 assert_eq!(AccessWords::for_language("pt_BR"), AccessWords::pt_br());
124 assert_eq!(AccessWords::for_language("de"), AccessWords::english());
125 }
126
127 #[test]
128 fn words_from_elsewhere_replace_by_key() {
129 let words =
130 AccessWords::pt_br().from_lookup(|key| (key == "a11y.saved").then(|| "Gravado: {0}".to_owned()));
131 assert_eq!(words.saved("Conta"), "Gravado: Conta");
132 assert_eq!(words.deleted(3), "3 registros apagados");
133 assert_eq!(words.deleted(1), "1 registro apagado");
134 }
135}