Skip to main content

json_gettext/common/
json_gettext.rs

1use std::collections::{BTreeMap, HashMap};
2
3#[cfg(feature = "regex")]
4use regex::Regex;
5
6use super::{Context, IntoKey, JSONGetTextBuilder, LookupKey};
7use crate::{JSONGetTextBuildError, JSONGetTextValue, text_lookup};
8
9/// A wrapper for context and a default key. **Keys** are usually considered as locales.
10#[derive(Debug)]
11pub struct JSONGetText<'a> {
12    default_key: crate::Key,
13    context:     Context<'a>,
14}
15
16impl<'a> JSONGetText<'a> {
17    /// Create a new `JSONGetTextBuilder` instance. You need to decide your default key at this stage.
18    #[inline]
19    pub fn build<K: IntoKey>(default_key: K) -> JSONGetTextBuilder<'a> {
20        JSONGetTextBuilder::new(default_key)
21    }
22
23    /// Create a new JSONGetText instance with context and a default key.
24    pub(crate) fn from_context_with_default_key(
25        default_key: crate::Key,
26        context: Context<'a>,
27        allow_extra_texts: bool,
28    ) -> Result<JSONGetText<'a>, JSONGetTextBuildError> {
29        let context = text_lookup::finalize_context(&default_key, context, allow_extra_texts)?;
30
31        Ok(JSONGetText {
32            default_key,
33            context,
34        })
35    }
36
37    /// Get the default key.
38    #[cfg(not(feature = "langid"))]
39    #[inline]
40    pub fn get_default_key(&self) -> &str {
41        self.default_key.as_str()
42    }
43
44    /// Get the default key.
45    #[cfg(feature = "langid")]
46    #[inline]
47    pub fn get_default_key(&self) -> crate::Key {
48        self.default_key
49    }
50
51    /// Get all keys in context.
52    #[cfg(not(feature = "langid"))]
53    pub fn get_keys(&self) -> Vec<&str> {
54        self.context.keys().map(|key| key.as_str()).collect()
55    }
56
57    /// Get all keys in context.
58    #[cfg(feature = "langid")]
59    pub fn get_keys(&self) -> Vec<crate::Key> {
60        self.context.keys().copied().collect()
61    }
62
63    /// Returns `true` if the context contains a value for the specified key.
64    #[inline]
65    pub fn contains_key<K: LookupKey>(&self, key: K) -> bool {
66        key.lookup(&self.context).is_some()
67    }
68
69    /// Get the texts owned by a key. Missing texts are **not** filled in from the default key; the default key's map is returned only when the key itself is absent.
70    #[inline]
71    pub fn get<K: LookupKey>(&self, key: K) -> &HashMap<String, JSONGetTextValue<'a>> {
72        key.lookup(&self.context).unwrap_or_else(|| self.default_map())
73    }
74
75    /// Get text from context.
76    #[inline]
77    pub fn get_text<T: AsRef<str>>(&self, text: T) -> Option<JSONGetTextValue<'_>> {
78        let map = self.default_map();
79
80        text_lookup::get_text(map, map, text.as_ref())
81    }
82
83    /// Get text from context with a specific key, falling back to the default key when the text is missing.
84    #[inline]
85    pub fn get_text_with_key<K: LookupKey, T: AsRef<str>>(
86        &self,
87        key: K,
88        text: T,
89    ) -> Option<JSONGetTextValue<'_>> {
90        let default_map = self.default_map();
91        let map = key.lookup(&self.context).unwrap_or(default_map);
92
93        text_lookup::get_text(map, default_map, text.as_ref())
94    }
95
96    /// Get multiple text from context. The output map is usually used for serialization.
97    pub fn get_multiple_text<'b, T: AsRef<str> + ?Sized>(
98        &self,
99        text_array: &[&'b T],
100    ) -> Option<BTreeMap<&'b str, JSONGetTextValue<'_>>> {
101        let map = self.default_map();
102
103        text_lookup::get_multiple_text(map, map, text_array)
104    }
105
106    /// Get multiple text from context with a specific key, falling back to the default key per text. The output map is usually used for serialization.
107    pub fn get_multiple_text_with_key<'b, K: LookupKey, T: AsRef<str> + ?Sized>(
108        &self,
109        key: K,
110        text_array: &[&'b T],
111    ) -> Option<BTreeMap<&'b str, JSONGetTextValue<'_>>> {
112        let default_map = self.default_map();
113        let map = key.lookup(&self.context).unwrap_or(default_map);
114
115        text_lookup::get_multiple_text(map, default_map, text_array)
116    }
117
118    /// Get filtered text from context by a Regex instance. The output map is usually used for serialization.
119    #[cfg(feature = "regex")]
120    pub fn get_filtered_text(&self, regex: &Regex) -> Option<BTreeMap<&str, JSONGetTextValue<'_>>> {
121        Some(text_lookup::get_filtered_text(self.default_map(), regex))
122    }
123
124    /// Get filtered text owned by a specific key by a Regex instance. Texts are not filled in from the default key. The output map is usually used for serialization.
125    #[cfg(feature = "regex")]
126    pub fn get_filtered_text_with_key<K: LookupKey>(
127        &self,
128        key: K,
129        regex: &Regex,
130    ) -> Option<BTreeMap<&str, JSONGetTextValue<'_>>> {
131        let map = key.lookup(&self.context).unwrap_or_else(|| self.default_map());
132
133        Some(text_lookup::get_filtered_text(map, regex))
134    }
135
136    /// The map of texts owned by the default key. The default key is always present, so this never panics.
137    #[inline]
138    fn default_map(&self) -> &HashMap<String, JSONGetTextValue<'a>> {
139        self.context.get(&self.default_key).unwrap()
140    }
141}