next_web_common/frequently/json_object.rs
1use serde::de::DeserializeOwned;
2use serde_json::Value;
3use std::{borrow::Cow, collections::HashMap};
4
5use crate::error::json_object_error::JsonObjectError;
6
7/// 定义一个可序列化和反序列化的 JSON 对象结构体。
8/// 该结构体封装了一个 `HashMap`,用于存储键值对,并支持多种操作接口。
9#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
10pub struct JsonObject {
11 /// 存储 JSON 键值对的核心数据结构。
12 raw_value: HashMap<Cow<'static, str>, Value>,
13 /// 是否保持键值对的顺序(暂时不支持)。
14 is_order: bool,
15}
16
17impl JsonObject {
18 /// 创建一个新的 `JsonObject` 实例。
19 ///
20 /// # 参数
21 /// - `is_order`: 是否保持键值对的顺序(当前未实现)。
22 ///
23 /// # 返回值
24 /// 返回一个初始化的 `JsonObject` 实例,默认容量为 12
25 pub fn new(is_order: bool) -> Self {
26 Self {
27 raw_value: HashMap::with_capacity(12),
28 is_order,
29 }
30 }
31
32 /// 从 JSON 字符串解析出指定类型的对象实例。
33 ///
34 /// # 参数
35 /// - `json_str`: 包含 JSON 数据的字符串。
36 ///
37 /// # 返回值
38 /// 如果解析成功,返回指定类型的对象;否则返回 `JsonObjectError::PaseError`。
39 pub fn parse_object<T: DeserializeOwned>(json_str: &str) -> Result<T, JsonObjectError> {
40 serde_json::from_str::<T>(json_str).map_err(|_| JsonObjectError::PaseError)
41 }
42
43 /// 检查键是否为空。
44 ///
45 /// # 参数
46 /// - `key`: 需要检查的键。
47 ///
48 /// # 返回值
49 /// 如果键为空,返回 `false`;否则返回 `true`。
50 fn check_key(&self, key: &str) -> bool {
51 if key.is_empty() {
52 return false;
53 }
54 true
55 }
56}
57
58/// 为 `JsonObject` 提供功能接口。
59impl JsonObject {
60 /// 获取 `JsonObject` 中键值对的数量。
61 ///
62 /// # 返回值
63 /// 返回键值对的总数。
64 fn size(&self) -> usize {
65 self.raw_value.len()
66 }
67
68 /// 检查 `JsonObject` 是否为空。
69 ///
70 /// # 返回值
71 /// 如果没有任何键值对,返回 `true`;否则返回 `false`。
72 fn is_empty(&self) -> bool {
73 self.raw_value.is_empty()
74 }
75
76 /// 检查 `JsonObject` 是否包含指定键。
77 ///
78 /// # 参数
79 /// - `key`: 需要检查的键。
80 ///
81 /// # 返回值
82 /// 如果包含指定键,返回 `true`;否则返回 `false`。
83 fn contains_key(&self, key: &str) -> bool {
84 self.raw_value.contains_key(key)
85 }
86
87 /// 根据键获取值并反序列化为指定类型。
88 ///
89 /// # 参数
90 /// - `key`: 需要查找的键。
91 ///
92 /// # 返回值
93 /// 如果键存在且反序列化成功,返回对应的值;否则返回 `None`
94 fn get<V: DeserializeOwned>(&self, key: &str) -> Option<V> {
95 self.raw_value
96 .get(key)
97 .and_then(|v| serde_json::from_value(v.clone()).ok())
98 }
99
100 /// 根据键获取值并反序列化为指定类型,如果键不存在则返回默认值。
101 ///
102 /// # 参数
103 /// - `key`: 需要查找的键。
104 /// - `default`: 默认值。
105 ///
106 /// # 返回值
107 /// 如果键存在且反序列化成功,返回对应的值;否则返回默认值。
108 fn get_or_default<V: DeserializeOwned>(&self, key: &str, default: V) -> V {
109 if let Some(v) = self.raw_value.get(key) {
110 return serde_json::from_value(v.clone()).unwrap_or(default);
111 }
112 default
113 }
114
115 /// 根据键获取浮点数值。
116 ///
117 /// # 参数
118 /// - `key`: 需要查找的键。
119 ///
120 /// # 返回值
121 /// 如果键存在且值为浮点数,返回对应的值;否则返回 `None`。
122 fn get_double(&self, key: &str) -> Option<f64> {
123 self.raw_value.get(key).and_then(|v| v.as_f64())
124 }
125
126 /// 根据键获取整数值。
127 ///
128 /// # 参数
129 /// - `key`: 需要查找的键。
130 ///
131 /// # 返回值
132 /// 如果键存在且值为整数,返回对应的值;否则返回 `None`。
133 fn get_int(&self, key: &str) -> Option<i64> {
134 self.raw_value.get(key).and_then(|v| v.as_i64())
135 }
136
137 /// 根据键获取无符号整数值。
138 ///
139 /// # 参数
140 /// - `key`: 需要查找的键。
141 ///
142 /// # 返回值
143 /// 如果键存在且值为无符号整数,返回对应的值;否则返回 `None`。
144 fn get_uint(&self, key: &str) -> Option<u64> {
145 self.raw_value.get(key).and_then(|v| v.as_u64())
146 }
147
148 /// 根据键获取字符串值。
149 ///
150 /// # 参数
151 /// - `key`: 需要查找的键。
152 ///
153 /// # 返回值
154 /// 如果键存在且值为字符串,返回对应的值;否则返回 `None`。
155 fn get_str(&self, key: &str) -> Option<&str> {
156 self.raw_value.get(key).and_then(|v| v.as_str())
157 }
158
159 /// 根据键获取布尔值。
160 ///
161 /// # 参数
162 /// - `key`: 需要查找的键。
163 ///
164 /// # 返回值
165 /// 如果键存在且值为布尔值,返回对应的值;否则返回 `None`。
166 fn get_bool(&self, key: &str) -> Option<bool> {
167 self.raw_value.get(key).and_then(|v| v.as_bool())
168 }
169
170 /// 根据键获取 JSON 数组,并反序列化为指定类型。
171 ///
172 /// # 参数
173 /// - `key`: 需要查找的键。
174 ///
175 /// # 返回值
176 /// 如果键存在且值为数组,返回反序列化后的列表;否则返回空列表。
177 fn get_json_array<V: DeserializeOwned>(&self, key: &str) -> Vec<V> {
178 self.raw_value
179 .get(key)
180 .and_then(|v| v.as_array())
181 .map(|arr| {
182 arr.iter()
183 .map(|v| serde_json::from_value(v.clone()).unwrap())
184 .collect()
185 })
186 .unwrap_or_default()
187 }
188
189 /// 设置指定键的值,如果键已存在则覆盖原有值。
190 ///
191 /// # 参数
192 /// - `key`: 需要设置的键。
193 /// - `value`: 需要设置的值。
194 ///
195 /// # 返回值
196 /// 如果键已存在,返回被覆盖的旧值;否则返回 `None`。
197 fn set<V: Into<Value>>(mut self, key: impl Into<Cow<'static, str>>, value: V) -> Self {
198 self.raw_value.insert(key.into(), value.into());
199 return self;
200 }
201
202 /// 设置指定键的值,如果键已存在则覆盖原有值。
203 ///
204 /// # 参数
205 /// - `key`: 需要设置的键。
206 /// - `value`: 需要设置的值。
207 ///
208 /// # 返回值
209 /// 如果键已存在,返回被覆盖的旧值;否则返回 `None`。
210 fn set_opt<V: Into<Value>>(&mut self, key: impl Into<Cow<'static, str>>, value: V) -> Option<Value> {
211 self.raw_value.insert(key.into(), value.into())
212 }
213
214 /// 设置指定键的值,如果键已存在则返回错误。
215 ///
216 /// # 参数
217 /// - `key`: 需要设置的键。
218 /// - `value`: 需要设置的值。
219 ///
220 /// # 返回值
221 /// 如果键不存在且设置成功,返回 `Ok(())`;否则返回相应的错误。
222 fn put_once<V: Into<Value>>(
223 &mut self,
224 key: impl Into<Cow<'static, str>>,
225 value: V,
226 ) -> Result<(), JsonObjectError> {
227 let key = key.into();
228 if !self.check_key(&key) {
229 return Err(JsonObjectError::KeyIsEmpty);
230 }
231 if self.raw_value.contains_key(&key) {
232 return Err(JsonObjectError::KeyAlreadyExists);
233 }
234 self.set_opt(key, value);
235 Ok(())
236 }
237
238 /// 设置指定键的值,如果值为 `null` 则返回错误。
239 ///
240 /// # 参数
241 /// - `key`: 需要设置的键。
242 /// - `value`: 需要设置的值。
243 ///
244 /// # 返回值
245 /// 如果值不为 `null` 且设置成功,返回 `Ok(())`;否则返回相应的错误。
246 fn put_opt<V: Into<Value>>(
247 &mut self,
248 key: impl Into<String>,
249 value: V,
250 ) -> Result<(), JsonObjectError> {
251 let key = key.into();
252 let value = value.into();
253 if !self.check_key(&key) {
254 return Err(JsonObjectError::KeyIsEmpty);
255 }
256
257 if value.is_null() {
258 return Err(JsonObjectError::KeyOrValueIsNull);
259 }
260
261 self.set_opt(key, value);
262 Ok(())
263 }
264
265 /// 将另一个可迭代的键值对集合中的所有键值对添加到 `JsonObject` 中。
266 ///
267 /// # 参数
268 /// - `data`: 包含键值对的可迭代集合。
269 fn put_all(&mut self, data: impl IntoIterator<Item = (Cow<'static, str>, Value)>) {
270 self.raw_value.extend(data);
271 }
272
273 /// 获取 `JsonObject` 的原始 `HashMap` 引用。
274 ///
275 /// # 返回值
276 /// 返回底层 `HashMap` 的不可变引用。
277 fn raw_value(&self) -> &HashMap<Cow<'static, str>, Value> {
278 &self.raw_value
279 }
280
281 /// 清空 `JsonObject` 中的所有键值对。
282 fn clear(&mut self) {
283 self.raw_value.clear()
284 }
285
286 /// 获取 `JsonObject` 中所有值的引用列表。
287 ///
288 /// # 返回值
289 /// 返回所有值的引用列表。
290 fn values(&self) -> Vec<&Value> {
291 self.raw_value.values().collect()
292 }
293
294 /// 获取 `JsonObject` 中所有键的引用列表。
295 ///
296 /// # 返回值
297 /// 返回所有键的引用列表。
298 fn keys(&self) -> Vec<&Cow<'static, str>> {
299 self.raw_value.keys().collect()
300 }
301
302 /// 将 `JsonObject` 转换为 JSON 字符串。
303 ///
304 /// # 返回值
305 /// 返回紧凑格式的 JSON 字符串。
306 fn to_json_string(&self) -> String {
307 serde_json::to_string(&self.raw_value).unwrap_or_default()
308 }
309
310 /// 将 `JsonObject` 转换为格式化的 JSON 字符串。
311 ///
312 /// # 返回值
313 /// 返回格式化的 JSON 字符串。
314 fn to_json_string_pretty(&self) -> String {
315 serde_json::to_string_pretty(&self.raw_value).unwrap_or_default()
316 }
317}
318
319/// 实现 `Default` 特性以提供默认的 `JsonObject` 实例。
320impl Default for JsonObject {
321 /// 创建一个默认的 `JsonObject` 实例。
322 ///
323 /// # 返回值
324 /// 返回一个初始化的 `JsonObject` 实例,默认容量为 12,`is_order` 为 `false`。
325 fn default() -> Self {
326 Self {
327 raw_value: HashMap::with_capacity(12),
328 is_order: false,
329 }
330 }
331}
332