json_gettext/key_string/
json_gettext.rs1use std::collections::HashMap;
2
3use regex::Regex;
4
5use super::{Context, JSONGetTextBuilder};
6use crate::{JSONGetTextBuildError, JSONGetTextValue};
7
8#[derive(Debug)]
10pub struct JSONGetText<'a> {
11 default_key: String,
12 context: Context<'a>,
13}
14
15impl<'a> JSONGetText<'a> {
16 #[inline]
18 pub fn build<S: Into<String>>(default_key: S) -> JSONGetTextBuilder<'a> {
19 JSONGetTextBuilder::new(default_key)
20 }
21
22 pub(crate) fn from_context_with_default_key<S: AsRef<str> + Into<String>>(
24 default_key: S,
25 mut context: Context<'a>,
26 ) -> Result<JSONGetText<'a>, JSONGetTextBuildError> {
27 if !context.contains_key(default_key.as_ref()) {
28 return Err(JSONGetTextBuildError::DefaultKeyNotFound);
29 }
30
31 let default_key = default_key.into();
32
33 let default_map = context.remove(&default_key).unwrap();
34
35 let mut inner_context = HashMap::new();
36
37 {
38 for (key, mut map) in context {
39 {
40 for map_key in map.keys() {
41 if !default_map.contains_key(map_key) {
42 return Err(JSONGetTextBuildError::TextInKeyNotInDefaultKey {
43 key,
44 text: map_key.clone(),
45 });
46 }
47 }
48 }
49
50 {
51 for map_key in default_map.keys() {
52 if !map.contains_key(map_key) {
53 map.insert(map_key.clone(), default_map.get(map_key).unwrap().clone());
54 }
55 }
56 }
57
58 inner_context.insert(key, map);
59 }
60
61 inner_context.insert(default_key.clone().into(), default_map);
62 }
63
64 Ok(JSONGetText {
65 default_key,
66 context: inner_context,
67 })
68 }
69
70 pub fn get_keys(&self) -> Vec<&str> {
72 self.context.keys().map(|key| key.as_str()).collect()
73 }
74
75 #[inline]
77 pub fn contains_key<K: AsRef<str>>(&self, key: K) -> bool {
78 self.context.contains_key(key.as_ref())
79 }
80
81 #[inline]
83 pub fn get_default_key(&self) -> &str {
84 &self.default_key
85 }
86
87 #[inline]
89 pub fn get<K: AsRef<str>>(&self, key: K) -> &HashMap<String, JSONGetTextValue<'a>> {
90 match self.context.get(key.as_ref()) {
91 Some(m) => m,
92 None => self.context.get(&self.default_key).unwrap(),
93 }
94 }
95
96 #[inline]
98 pub fn get_text<T: AsRef<str>>(&'a self, text: T) -> Option<JSONGetTextValue<'a>> {
99 let map = self.context.get(&self.default_key).unwrap();
100
101 map.get(text.as_ref()).map(|v| v.clone_borrowed())
102 }
103
104 #[inline]
106 pub fn get_text_with_key<K: AsRef<str>, T: AsRef<str>>(
107 &'a self,
108 key: K,
109 text: T,
110 ) -> Option<JSONGetTextValue<'a>> {
111 let map = self
112 .context
113 .get(key.as_ref())
114 .unwrap_or_else(|| self.context.get(&self.default_key).unwrap());
115
116 map.get(text.as_ref()).map(|v| v.clone_borrowed())
117 }
118
119 pub fn get_multiple_text<'b, T: AsRef<str> + ?Sized>(
121 &self,
122 text_array: &[&'b T],
123 ) -> Option<HashMap<&'b str, JSONGetTextValue>> {
124 let map = self.context.get(&self.default_key).unwrap();
125
126 let mut new_map = HashMap::new();
127
128 for &text in text_array.iter() {
129 let text = text.as_ref();
130 let value = map.get(text)?;
131 new_map.insert(text, value.clone_borrowed());
132 }
133
134 Some(new_map)
135 }
136
137 pub fn get_multiple_text_with_key<'b, K: AsRef<str>, T: AsRef<str> + ?Sized>(
139 &'a self,
140 key: K,
141 text_array: &[&'b T],
142 ) -> Option<HashMap<&'b str, JSONGetTextValue<'a>>> {
143 let map = self
144 .context
145 .get(key.as_ref())
146 .unwrap_or_else(|| self.context.get(&self.default_key).unwrap());
147
148 let mut new_map = HashMap::new();
149
150 for &text in text_array.iter() {
151 let text = text.as_ref();
152 let value = map.get(text)?;
153 new_map.insert(text, value.clone_borrowed());
154 }
155
156 Some(new_map)
157 }
158
159 pub fn get_filtered_text(
161 &'a self,
162 regex: &Regex,
163 ) -> Option<HashMap<&'a str, JSONGetTextValue<'a>>> {
164 let map = self.context.get(&self.default_key).unwrap();
165
166 let mut new_map = HashMap::new();
167
168 for (key, value) in map.iter() {
169 if !regex.is_match(key) {
170 continue;
171 }
172 new_map.insert(key.as_str(), value.clone_borrowed());
173 }
174
175 Some(new_map)
176 }
177
178 pub fn get_filtered_text_with_key<K: AsRef<str>>(
180 &'a self,
181 key: K,
182 regex: &Regex,
183 ) -> Option<HashMap<&'a str, JSONGetTextValue<'a>>> {
184 let map = self
185 .context
186 .get(key.as_ref())
187 .unwrap_or_else(|| self.context.get(&self.default_key).unwrap());
188
189 let mut new_map = HashMap::new();
190
191 for (key, value) in map.iter() {
192 if !regex.is_match(key) {
193 continue;
194 }
195 new_map.insert(key.as_str(), value.clone_borrowed());
196 }
197
198 Some(new_map)
199 }
200}