Skip to main content

bare_config/
json.rs

1//! JSON format support for configuration content.
2//!
3//! This module provides the `JsonContent` type for working
4//! with JSON configuration files.
5//!
6//! # Features
7//!
8//! - Full CRUD operations (select, insert, update, delete, upsert)
9//! - Pretty-printed output
10//! - Consistent round-trip serialization
11//!
12//! # Example
13//!
14//! ```
15//! use bare_config::json::JsonContent;
16//! use bare_config::{ConfigContent, key::Key};
17//! use bare_config::value::Value;
18//! use std::str::FromStr;
19//!
20//! // Parse JSON configuration
21//! let config = JsonContent::from_str(r#"{"database": {"url": "localhost"}}"#).unwrap();
22//!
23//! // Select a value
24//! let value = config.select(&Key::from_str(".database.url").unwrap()).unwrap();
25//! assert_eq!(value.as_str(), Some("localhost"));
26//!
27//! // Insert a new value
28//! let mut config = JsonContent::from_str("{}").unwrap();
29//! config.insert(&Key::from_str(".server.port").unwrap(), &Value::string("8080")).unwrap();
30//!
31//! // Format as string (pretty-printed)
32//! let output = config.to_string();
33//! println!("{}", output);
34//! ```
35
36use core::fmt;
37use core::str::FromStr;
38
39use crate::ConfigContent;
40use crate::error::{ConfigError, ConfigResult};
41use crate::key::{Key, KeySegment};
42use crate::value::Value;
43use serde_json::Value as JsonValue;
44
45/// JSON configuration content.
46///
47/// This type provides CRUD operations for JSON configuration data.
48#[derive(Debug, Clone, PartialEq)]
49pub struct JsonContent {
50    data: JsonValue,
51}
52
53#[allow(dead_code)]
54impl JsonContent {
55    /// Creates a new JsonContent from a serde_json::Value.
56    pub fn from_value(value: JsonValue) -> Self {
57        Self { data: value }
58    }
59
60    /// Returns a reference to the underlying serde_json::Value.
61    pub fn as_value(&self) -> &JsonValue {
62        &self.data
63    }
64
65    /// Converts to the underlying serde_json::Value.
66    pub fn into_value(self) -> JsonValue {
67        self.data
68    }
69
70    fn get_value_at_key(&self, key: &Key) -> ConfigResult<&JsonValue> {
71        let mut current = &self.data;
72
73        for segment in key.segments() {
74            match segment {
75                KeySegment::Key(s) => {
76                    current = match current {
77                        JsonValue::Object(obj) => obj
78                            .get(s)
79                            .ok_or_else(|| ConfigError::KeyNotFound(key.to_key_string()))?,
80                        _ => {
81                            return Err(ConfigError::KeyNotFound(key.to_key_string()));
82                        }
83                    };
84                }
85                KeySegment::Index(i) => {
86                    current = match current {
87                        JsonValue::Array(arr) => arr
88                            .get(*i)
89                            .ok_or_else(|| ConfigError::KeyNotFound(key.to_key_string()))?,
90                        _ => {
91                            return Err(ConfigError::KeyNotFound(key.to_key_string()));
92                        }
93                    };
94                }
95                KeySegment::Attribute(_) => {
96                    return Err(ConfigError::InvalidKey(
97                        "JSON does not support attributes".to_string(),
98                    ));
99                }
100            }
101        }
102
103        Ok(current)
104    }
105
106    fn contains_key_at(&self, key: &Key) -> bool {
107        self.get_value_at_key(key).is_ok()
108    }
109
110    fn keys_at(&self) -> Vec<Key> {
111        match &self.data {
112            JsonValue::Object(obj) => obj
113                .keys()
114                .filter_map(|k| Key::from_str(&format!(".{k}")).ok())
115                .collect(),
116            JsonValue::Array(arr) => (0..arr.len())
117                .filter_map(|i| Key::from_str(&format!(".[{i}]")).ok())
118                .collect(),
119            _ => vec![],
120        }
121    }
122
123    fn len_at(&self) -> usize {
124        match &self.data {
125            JsonValue::Object(obj) => obj.len(),
126            JsonValue::Array(arr) => arr.len(),
127            _ => 0,
128        }
129    }
130
131    fn delete_at(&mut self, key: &Key) -> ConfigResult<()> {
132        if key.segments().is_empty() {
133            return Err(ConfigError::DeleteError("Cannot delete root".to_string()));
134        }
135
136        let segments = key.segments();
137        let last_idx = segments.len() - 1;
138
139        let mut current = &mut self.data;
140
141        for (i, segment) in segments.iter().enumerate() {
142            if i == last_idx {
143                match segment {
144                    KeySegment::Key(s) => {
145                        if let JsonValue::Object(obj) = current {
146                            drop(obj.remove(s));
147                            return Ok(());
148                        }
149                    }
150                    KeySegment::Index(idx) => {
151                        if let JsonValue::Array(arr) = current {
152                            if *idx < arr.len() {
153                                drop(arr.remove(*idx));
154                                return Ok(());
155                            }
156                        }
157                    }
158                    KeySegment::Attribute(_) => {
159                        return Err(ConfigError::InvalidKey(
160                            "JSON does not support attributes".to_string(),
161                        ));
162                    }
163                }
164            } else {
165                match segment {
166                    KeySegment::Key(s) => {
167                        if let JsonValue::Object(obj) = current {
168                            if let Some(next) = obj.get_mut(s) {
169                                current = next;
170                            } else {
171                                return Err(ConfigError::KeyNotFound(key.to_key_string()));
172                            }
173                        } else {
174                            return Err(ConfigError::KeyNotFound(key.to_key_string()));
175                        }
176                    }
177                    KeySegment::Index(idx) => {
178                        if let JsonValue::Array(arr) = current {
179                            if let Some(next) = arr.get_mut(*idx) {
180                                current = next;
181                            } else {
182                                return Err(ConfigError::KeyNotFound(key.to_key_string()));
183                            }
184                        } else {
185                            return Err(ConfigError::KeyNotFound(key.to_key_string()));
186                        }
187                    }
188                    KeySegment::Attribute(_) => {
189                        return Err(ConfigError::InvalidKey(
190                            "JSON does not support attributes".to_string(),
191                        ));
192                    }
193                }
194            }
195        }
196
197        Err(ConfigError::KeyNotFound(key.to_key_string()))
198    }
199
200    fn insert_at(&mut self, key: &Key, value: &Value) -> ConfigResult<()> {
201        if self.contains_key_at(key) {
202            return Err(ConfigError::KeyAlreadyExists(key.to_key_string()));
203        }
204
205        self.upsert_at(key, value)
206    }
207
208    fn update_at(&mut self, key: &Key, value: &Value) -> ConfigResult<()> {
209        if !self.contains_key_at(key) {
210            return Err(ConfigError::KeyDoesNotExist(key.to_key_string()));
211        }
212
213        self.upsert_at(key, value)
214    }
215
216    fn upsert_at(&mut self, key: &Key, value: &Value) -> ConfigResult<()> {
217        if key.segments().is_empty() {
218            self.data = json_value_from_value(value);
219            return Ok(());
220        }
221
222        let segments = key.segments();
223        let last_idx = segments.len() - 1;
224
225        let mut current = &mut self.data;
226
227        for (i, segment) in segments.iter().enumerate() {
228            if i == last_idx {
229                match segment {
230                    KeySegment::Key(s) => {
231                        if let JsonValue::Object(obj) = current {
232                            drop(obj.insert(s.clone(), json_value_from_value(value)));
233                            return Ok(());
234                        }
235                    }
236                    KeySegment::Index(idx) => {
237                        if let JsonValue::Array(arr) = current {
238                            if *idx < arr.len() {
239                                arr[*idx] = json_value_from_value(value);
240                            } else if *idx == arr.len() {
241                                arr.push(json_value_from_value(value));
242                            } else {
243                                return Err(ConfigError::KeyNotFound(key.to_key_string()));
244                            }
245                            return Ok(());
246                        }
247                    }
248                    KeySegment::Attribute(_) => {
249                        return Err(ConfigError::InvalidKey(
250                            "JSON does not support attributes".to_string(),
251                        ));
252                    }
253                }
254            } else {
255                match segment {
256                    KeySegment::Key(s) => {
257                        let next = match current {
258                            JsonValue::Object(obj) => {
259                                let key_exists = obj.contains_key(s);
260                                if !key_exists {
261                                    drop(obj.insert(
262                                        s.clone(),
263                                        JsonValue::Object(serde_json::Map::new()),
264                                    ));
265                                }
266                                obj.get_mut(s)
267                                    .ok_or_else(|| ConfigError::KeyNotFound(key.to_key_string()))?
268                            }
269                            _ => {
270                                return Err(ConfigError::KeyNotFound(key.to_key_string()));
271                            }
272                        };
273                        current = next;
274                    }
275                    KeySegment::Index(idx) => {
276                        let next = match current {
277                            JsonValue::Array(arr) => {
278                                if *idx < arr.len() {
279                                    &mut arr[*idx]
280                                } else if *idx == arr.len() {
281                                    arr.push(JsonValue::Null);
282                                    arr.last_mut().ok_or_else(|| {
283                                        ConfigError::KeyNotFound(key.to_key_string())
284                                    })?
285                                } else {
286                                    return Err(ConfigError::KeyNotFound(key.to_key_string()));
287                                }
288                            }
289                            _ => {
290                                return Err(ConfigError::KeyNotFound(key.to_key_string()));
291                            }
292                        };
293                        current = next;
294                    }
295                    KeySegment::Attribute(_) => {
296                        return Err(ConfigError::InvalidKey(
297                            "JSON does not support attributes".to_string(),
298                        ));
299                    }
300                }
301            }
302        }
303
304        Ok(())
305    }
306}
307
308impl ConfigContent for JsonContent {
309    fn select(&self, key: &Key) -> ConfigResult<Value> {
310        let json_value = self.get_value_at_key(key)?;
311        Ok(value_from_json_value(json_value))
312    }
313
314    fn insert(&mut self, key: &Key, value: &Value) -> ConfigResult<()> {
315        self.insert_at(key, value)
316    }
317
318    fn update(&mut self, key: &Key, value: &Value) -> ConfigResult<()> {
319        self.update_at(key, value)
320    }
321
322    fn delete(&mut self, key: &Key) -> ConfigResult<()> {
323        self.delete_at(key)
324    }
325
326    fn upsert(&mut self, key: &Key, value: &Value) -> ConfigResult<()> {
327        self.upsert_at(key, value)
328    }
329}
330
331impl FromStr for JsonContent {
332    type Err = ConfigError;
333
334    fn from_str(s: &str) -> Result<Self, Self::Err> {
335        let value: JsonValue =
336            serde_json::from_str(s).map_err(|e| ConfigError::ParseError(e.to_string()))?;
337        Ok(JsonContent { data: value })
338    }
339}
340
341impl fmt::Display for JsonContent {
342    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343        let output = serde_json::to_string_pretty(&self.data).map_err(|_| fmt::Error)?;
344        write!(f, "{}", output)
345    }
346}
347
348fn value_from_json_value(json: &JsonValue) -> Value {
349    match json {
350        JsonValue::Null => Value::Null,
351        JsonValue::Bool(b) => Value::Bool(*b),
352        JsonValue::Number(n) => {
353            if let Some(i) = n.as_i64() {
354                Value::Integer(i)
355            } else if let Some(f) = n.as_f64() {
356                Value::Float(f)
357            } else {
358                Value::Null
359            }
360        }
361        JsonValue::String(s) => Value::String(s.clone()),
362        JsonValue::Array(arr) => Value::Array(arr.iter().map(value_from_json_value).collect()),
363        JsonValue::Object(obj) => Value::Map(
364            obj.iter()
365                .map(|(k, v)| (k.clone(), value_from_json_value(v)))
366                .collect(),
367        ),
368    }
369}
370
371fn json_value_from_value(value: &Value) -> JsonValue {
372    match value {
373        Value::Null => JsonValue::Null,
374        Value::Bool(b) => JsonValue::Bool(*b),
375        Value::Integer(i) => JsonValue::Number(serde_json::Number::from(*i)),
376        Value::Float(f) => {
377            // JSON doesn't support NaN/Infinity, serialize as string
378            if f.is_nan() {
379                JsonValue::String("NaN".to_string())
380            } else if f.is_infinite() {
381                if f.is_sign_positive() {
382                    JsonValue::String("Infinity".to_string())
383                } else {
384                    JsonValue::String("-Infinity".to_string())
385                }
386            } else {
387                serde_json::Number::from_f64(*f)
388                    .map(JsonValue::Number)
389                    .unwrap_or(JsonValue::Null)
390            }
391        }
392        Value::String(s) => JsonValue::String(s.clone()),
393        Value::Array(arr) => JsonValue::Array(arr.iter().map(json_value_from_value).collect()),
394        Value::Map(m) => {
395            let mut obj = serde_json::Map::new();
396            for (k, v) in m {
397                drop(obj.insert(k.clone(), json_value_from_value(v)));
398            }
399            JsonValue::Object(obj)
400        }
401    }
402}
403
404impl TryFrom<JsonValue> for Value {
405    type Error = ConfigError;
406
407    fn try_from(json: JsonValue) -> ConfigResult<Self> {
408        Ok(value_from_json_value(&json))
409    }
410}
411
412impl From<Value> for JsonValue {
413    fn from(value: Value) -> Self {
414        json_value_from_value(&value)
415    }
416}
417
418#[cfg(test)]
419mod tests {
420    use super::*;
421
422    #[test]
423    fn test_json_from_str() {
424        let content = JsonContent::from_str(r#"{"key": "value"}"#).expect("test should succeed");
425        assert!(
426            content
427                .select(&Key::from_str(".key").expect("test should succeed"))
428                .is_ok()
429        );
430    }
431
432    #[test]
433    fn test_json_to_string() {
434        let content = JsonContent::from_str(r#"{"key": "value"}"#).expect("test should succeed");
435        let s = content.to_string();
436        assert!(s.contains("key"));
437        assert!(s.contains("value"));
438    }
439
440    #[test]
441    fn test_json_select() {
442        let content = JsonContent::from_str(r#"{"name": "test"}"#).expect("test should succeed");
443        let value = content
444            .select(&Key::from_str(".name").expect("test should succeed"))
445            .expect("test should succeed");
446        assert_eq!(value.as_str(), Some("test"));
447    }
448
449    #[test]
450    fn test_json_select_nested() {
451        let content = JsonContent::from_str(r#"{"a": {"b": "c"}}"#).expect("test should succeed");
452        let value = content
453            .select(&Key::from_str(".a.b").expect("test should succeed"))
454            .expect("test should succeed");
455        assert_eq!(value.as_str(), Some("c"));
456    }
457
458    #[test]
459    fn test_json_select_array() {
460        let content =
461            JsonContent::from_str(r#"{"items": [1, 2, 3]}"#).expect("test should succeed");
462        let value = content
463            .select(&Key::from_str(".items[0]").expect("test should succeed"))
464            .expect("test should succeed");
465        assert_eq!(value.as_integer(), Some(1));
466    }
467
468    #[test]
469    fn test_json_insert() {
470        let mut content = JsonContent::from_str(r#"{"items": []}"#).expect("test should succeed");
471        content
472            .insert(
473                &Key::from_str(".name").expect("test should succeed"),
474                &Value::string("test"),
475            )
476            .expect("test should succeed");
477        let value = content
478            .select(&Key::from_str(".name").expect("test should succeed"))
479            .expect("test should succeed");
480        assert_eq!(value.as_str(), Some("test"));
481    }
482
483    #[test]
484    fn test_json_insert_exists() {
485        let mut content = JsonContent::from_str(r#"{"name": "old"}"#).expect("test should succeed");
486        let result = content.insert(
487            &Key::from_str(".name").expect("test should succeed"),
488            &Value::string("new"),
489        );
490        assert!(result.is_err());
491    }
492
493    #[test]
494    fn test_json_update() {
495        let mut content = JsonContent::from_str(r#"{"name": "old"}"#).expect("test should succeed");
496        content
497            .update(
498                &Key::from_str(".name").expect("test should succeed"),
499                &Value::string("new"),
500            )
501            .expect("test should succeed");
502        let value = content
503            .select(&Key::from_str(".name").expect("test should succeed"))
504            .expect("test should succeed");
505        assert_eq!(value.as_str(), Some("new"));
506    }
507
508    #[test]
509    fn test_json_update_not_exists() {
510        let mut content = JsonContent::from_str(r#"{"items": []}"#).expect("test should succeed");
511        let result = content.update(
512            &Key::from_str(".name").expect("test should succeed"),
513            &Value::string("test"),
514        );
515        assert!(result.is_err());
516    }
517
518    #[test]
519    fn test_json_delete() {
520        let mut content =
521            JsonContent::from_str(r#"{"name": "test"}"#).expect("test should succeed");
522        content
523            .delete(&Key::from_str(".name").expect("test should succeed"))
524            .expect("test should succeed");
525        assert!(
526            content
527                .select(&Key::from_str(".name").expect("test should succeed"))
528                .is_err()
529        );
530    }
531
532    #[test]
533    fn test_json_upsert_insert() {
534        let mut content = JsonContent::from_str(r#"{"items": []}"#).expect("test should succeed");
535        content
536            .upsert(
537                &Key::from_str(".name").expect("test should succeed"),
538                &Value::string("test"),
539            )
540            .expect("test should succeed");
541        let value = content
542            .select(&Key::from_str(".name").expect("test should succeed"))
543            .expect("test should succeed");
544        assert_eq!(value.as_str(), Some("test"));
545    }
546
547    #[test]
548    fn test_json_upsert_update() {
549        let mut content = JsonContent::from_str(r#"{"name": "old"}"#).expect("test should succeed");
550        content
551            .upsert(
552                &Key::from_str(".name").expect("test should succeed"),
553                &Value::string("new"),
554            )
555            .expect("test should succeed");
556        let value = content
557            .select(&Key::from_str(".name").expect("test should succeed"))
558            .expect("test should succeed");
559        assert_eq!(value.as_str(), Some("new"));
560    }
561
562    #[test]
563    fn test_json_contains_key() {
564        let content = JsonContent::from_str(r#"{"name": "test"}"#).expect("test should succeed");
565        assert!(
566            content
567                .select(&Key::from_str(".name").expect("test should succeed"))
568                .is_ok()
569        );
570        assert!(
571            content
572                .select(&Key::from_str(".missing").expect("test should succeed"))
573                .is_err()
574        );
575    }
576
577    #[test]
578    fn test_json_display_is_stable_and_pretty() {
579        let content = JsonContent::from_str(r#"{"b":2,"a":{"x":1}}"#).expect("test should succeed");
580        let first = content.to_string();
581        let second = content.to_string();
582        assert_eq!(first, second);
583        assert!(first.contains("\n"));
584    }
585
586    #[test]
587    fn test_json_select_not_found() {
588        let content = JsonContent::from_str(r#"{"a": 1}"#).expect("test should succeed");
589        let result = content.select(&Key::from_str(".missing").expect("test should succeed"));
590        assert!(result.is_err());
591    }
592
593    #[test]
594    fn test_json_array() {
595        let content = JsonContent::from_str(r#"[1, 2, 3]"#).expect("test should succeed");
596        let value = content
597            .select(&Key::from_str(".[0]").expect("test should succeed"))
598            .expect("test should succeed");
599        assert_eq!(value.as_integer(), Some(1));
600    }
601
602    #[test]
603    fn test_json_nested_array() {
604        let content = JsonContent::from_str(r#"{"users": [{"name": "alice"}, {"name": "bob"}]}"#)
605            .expect("test should succeed");
606        let value = content
607            .select(&Key::from_str(".users[0].name").expect("test should succeed"))
608            .expect("test should succeed");
609        assert_eq!(value.as_str(), Some("alice"));
610    }
611
612    #[test]
613    fn test_json_insert_array() {
614        let mut content = JsonContent::from_str(r#"{"items": []}"#).expect("test should succeed");
615        content
616            .upsert(
617                &Key::from_str(".items[0]").expect("test should succeed"),
618                &Value::integer(1),
619            )
620            .expect("test should succeed");
621        content
622            .upsert(
623                &Key::from_str(".items[1]").expect("test should succeed"),
624                &Value::integer(2),
625            )
626            .expect("test should succeed");
627
628        let value = content
629            .select(&Key::from_str(".items[1]").expect("test should succeed"))
630            .expect("test should succeed");
631        assert_eq!(value.as_integer(), Some(2));
632    }
633
634    #[test]
635    fn test_json_delete_array_element() {
636        let mut content = JsonContent::from_str(r#"[1, 2, 3]"#).expect("test should succeed");
637        content
638            .delete(&Key::from_str(".[1]").expect("test should succeed"))
639            .expect("test should succeed");
640
641        let value = content
642            .select(&Key::from_str(".[0]").expect("test should succeed"))
643            .expect("test should succeed");
644        assert_eq!(value.as_integer(), Some(1));
645
646        let value = content
647            .select(&Key::from_str(".[1]").expect("test should succeed"))
648            .expect("test should succeed");
649        assert_eq!(value.as_integer(), Some(3));
650    }
651
652    #[test]
653    fn test_json_value_conversion() {
654        let json = JsonValue::String("test".to_string());
655        let value: Value = json.try_into().expect("test should succeed");
656        assert_eq!(value.as_str(), Some("test"));
657
658        let value = Value::integer(42);
659        let json: JsonValue = value.into();
660        assert_eq!(json.as_str(), None);
661    }
662
663    #[test]
664    fn test_json_from_value() {
665        let json = serde_json::json!({"key": "value"});
666        let content = JsonContent::from_value(json);
667        let value = content
668            .select(&Key::from_str(".key").expect("test should succeed"))
669            .expect("test should succeed");
670        assert_eq!(value.as_str(), Some("value"));
671    }
672
673    #[test]
674    fn test_json_into_value() {
675        let content = JsonContent::from_str(r#"{"key": "value"}"#).expect("test should succeed");
676        let json = content.into_value();
677        assert_eq!(
678            json.get("key").expect("test should succeed").as_str(),
679            Some("value")
680        );
681    }
682
683    #[test]
684    fn test_json_null_value() {
685        let content = JsonContent::from_str(r#"{"key": null}"#).expect("test should succeed");
686        let value = content
687            .select(&Key::from_str(".key").expect("test should succeed"))
688            .expect("test should succeed");
689        assert!(value.is_null());
690    }
691
692    #[test]
693    fn test_json_boolean_values() {
694        let content =
695            JsonContent::from_str(r#"{"t": true, "f": false}"#).expect("test should succeed");
696        let t = content
697            .select(&Key::from_str(".t").expect("test should succeed"))
698            .expect("test should succeed");
699        let f = content
700            .select(&Key::from_str(".f").expect("test should succeed"))
701            .expect("test should succeed");
702        assert_eq!(t.as_bool(), Some(true));
703        assert_eq!(f.as_bool(), Some(false));
704    }
705
706    #[test]
707    fn test_json_integer_values() {
708        let content = JsonContent::from_str(r#"{"int": 42, "neg": -17, "zero": 0}"#)
709            .expect("test should succeed");
710        assert_eq!(
711            content
712                .select(&Key::from_str(".int").expect("test should succeed"))
713                .expect("test should succeed")
714                .as_integer(),
715            Some(42)
716        );
717        assert_eq!(
718            content
719                .select(&Key::from_str(".neg").expect("test should succeed"))
720                .expect("test should succeed")
721                .as_integer(),
722            Some(-17)
723        );
724        assert_eq!(
725            content
726                .select(&Key::from_str(".zero").expect("test should succeed"))
727                .expect("test should succeed")
728                .as_integer(),
729            Some(0)
730        );
731    }
732
733    #[test]
734    fn test_json_float_values() {
735        let content = JsonContent::from_str(r#"{"pi": 3.14, "exp": 1e10, "neg": -2.5}"#)
736            .expect("test should succeed");
737        let pi = content
738            .select(&Key::from_str(".pi").expect("test should succeed"))
739            .expect("test should succeed")
740            .as_float()
741            .expect("test should succeed");
742        assert!((pi - 3.14).abs() < 1e-6);
743        let exp = content
744            .select(&Key::from_str(".exp").expect("test should succeed"))
745            .expect("test should succeed")
746            .as_float()
747            .expect("test should succeed");
748        assert!((exp - 1e10).abs() < 1.0);
749    }
750
751    #[test]
752    fn test_json_string_unicode() {
753        let content = JsonContent::from_str(r#"{"text": "hello"}"#).expect("test should succeed");
754        let value = content
755            .select(&Key::from_str(".text").expect("test should succeed"))
756            .expect("test should succeed");
757        assert_eq!(value.as_str(), Some("hello"));
758    }
759
760    #[test]
761    fn test_json_string_escapes() {
762        let content =
763            JsonContent::from_str(r#"{"text": "line1\nline2\ttab"}"#).expect("test should succeed");
764        let value = content
765            .select(&Key::from_str(".text").expect("test should succeed"))
766            .expect("test should succeed");
767        assert_eq!(value.as_str(), Some("line1\nline2\ttab"));
768    }
769
770    #[test]
771    fn test_json_empty_array() {
772        let content = JsonContent::from_str(r#"{"arr": []}"#).expect("test should succeed");
773        let value = content
774            .select(&Key::from_str(".arr").expect("test should succeed"))
775            .expect("test should succeed");
776        assert!(value.as_array().expect("test should succeed").is_empty());
777    }
778
779    #[test]
780    fn test_json_empty_object() {
781        let content = JsonContent::from_str(r#"{"obj": {}}"#).expect("test should succeed");
782        let value = content
783            .select(&Key::from_str(".obj").expect("test should succeed"))
784            .expect("test should succeed");
785        assert!(value.as_map().expect("test should succeed").is_empty());
786    }
787
788    #[test]
789    fn test_json_deeply_nested() {
790        let content = JsonContent::from_str(r#"{"a": {"b": {"c": {"d": "value"}}}}"#)
791            .expect("test should succeed");
792        let value = content
793            .select(&Key::from_str(".a.b.c.d").expect("test should succeed"))
794            .expect("test should succeed");
795        assert_eq!(value.as_str(), Some("value"));
796    }
797
798    #[test]
799    fn test_json_array_of_objects() {
800        let content = JsonContent::from_str(r#"{"users": [{"name": "Alice"}, {"name": "Bob"}]}"#)
801            .expect("test should succeed");
802        let value = content
803            .select(&Key::from_str(".users[0].name").expect("test should succeed"))
804            .expect("test should succeed");
805        assert_eq!(value.as_str(), Some("Alice"));
806    }
807
808    #[test]
809    fn test_json_delete_nested_key() {
810        let mut content =
811            JsonContent::from_str(r#"{"a": {"b": "c"}}"#).expect("test should succeed");
812        content
813            .delete(&Key::from_str(".a.b").expect("test should succeed"))
814            .expect("test should succeed");
815        assert!(
816            content
817                .select(&Key::from_str(".a.b").expect("test should succeed"))
818                .is_err()
819        );
820    }
821
822    #[test]
823    fn test_json_update_nested_key() {
824        let mut content =
825            JsonContent::from_str(r#"{"a": {"b": "old"}}"#).expect("test should succeed");
826        content
827            .update(
828                &Key::from_str(".a.b").expect("test should succeed"),
829                &Value::string("new"),
830            )
831            .expect("test should succeed");
832        let value = content
833            .select(&Key::from_str(".a.b").expect("test should succeed"))
834            .expect("test should succeed");
835        assert_eq!(value.as_str(), Some("new"));
836    }
837
838    #[test]
839    fn test_json_special_numbers() {
840        let content =
841            JsonContent::from_str(r#"{"max": 9007199254740991, "float": 1.7976931348623157e308}"#)
842                .expect("test should succeed");
843        assert!(
844            content
845                .select(&Key::from_str(".max").expect("test should succeed"))
846                .expect("test should succeed")
847                .as_integer()
848                .is_some()
849        );
850        assert!(
851            content
852                .select(&Key::from_str(".float").expect("test should succeed"))
853                .expect("test should succeed")
854                .as_float()
855                .is_some()
856        );
857    }
858}