anyval/lib.rs
1#![doc = include_str!("../README.md")]
2#![warn(missing_docs, missing_debug_implementations)]
3
4mod string;
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7use std::{
8 borrow::Cow,
9 collections::HashMap,
10 fmt::{Debug, Display},
11};
12pub use string::*;
13
14#[derive(Debug, Clone)]
15/// A map of string keys to dynamically typed values.
16///
17/// `Map` is a wrapper around a `HashMap<String, Value>` that provides a convenient
18/// way to store and access heterogeneous data with string keys.
19///
20/// # Examples
21///
22/// ```
23/// use anyval::Map;
24///
25/// let mut m = Map::new();
26/// m["key"] = (10.0).into();
27/// m["key2"] = "string value".into();
28///
29/// // or using map! macro
30/// use anyval::map;
31/// let m2 = map! {
32/// "key" => 10.0,
33/// "key2" => "string value",
34/// };
35/// ```
36pub struct Map {
37 inner: Box<HashMap<String, Value>>,
38}
39
40impl Map {
41 /// Creates an empty `Map`.
42 ///
43 /// The map is initially created with a capacity of 0, so it will not allocate until it
44 /// is first inserted into.
45 ///
46 /// # Examples
47 ///
48 /// ```
49 /// use anyval::Map;
50 ///
51 /// let mut map = Map::new();
52 /// ```
53 pub fn new() -> Self {
54 Self {
55 inner: Box::new(HashMap::new()),
56 }
57 }
58 /// Creates an empty `Map` with at least the specified capacity.
59 ///
60 /// The map will be able to hold at least `capacity` elements without
61 /// reallocating. This method is allowed to allocate for more elements than
62 /// `capacity`. If `capacity` is 0, the map will not allocate.
63 ///
64 /// # Examples
65 ///
66 /// ```
67 /// use anyval::Map;
68 ///
69 /// let mut map = Map::with_capacity(10);
70 /// ```
71 pub fn with_capacity(capacity: usize) -> Self {
72 Self {
73 inner: Box::new(HashMap::with_capacity(capacity)),
74 }
75 }
76
77 #[cfg(all(feature = "json"))]
78 /// Deserialises a JSON string into a `Map`.
79 ///
80 /// Returns a `serde_json::Error` if the JSON cannot be parsed or does not
81 /// represent a valid map structure.
82 ///
83 /// # Examples
84 ///
85 /// ```
86 /// use anyval::Map;
87 ///
88 /// let json = r#"{"key":"value","num":42}"#;
89 /// let map = Map::from_json(json).unwrap();
90 /// assert_eq!(map["key"].as_str(), "value");
91 /// assert_eq!(map["num"].as_int(), 42);
92 /// ```
93 pub fn from_json(s: &str) -> Result<Self, serde_json::Error> {
94 serde_json::from_str(s)
95 }
96
97 /// Serialises the map to a JSON string.
98 ///
99 /// Returns a `serde_json::Error` if the map cannot be serialised.
100 ///
101 /// # Examples
102 ///
103 /// ```
104 /// use anyval::Map;
105 ///
106 /// let mut map = Map::new();
107 /// map["key"] = "value".into();
108 /// let json = map.to_json().unwrap();
109 /// assert_eq!(json, r#"{"key":"value"}"#);
110 /// ```
111 ///
112 /// # Nested example
113 ///
114 /// ```
115 /// use anyval::{Map, Value};
116 ///
117 /// let mut map = Map::new();
118 /// let mut nested = Map::new();
119 /// nested["inner"] = "value".into();
120 /// map["outer"] = Value::Map(nested);
121 /// let json = map.to_json().unwrap();
122 /// assert!(json.contains("outer"));
123 /// assert!(json.contains("inner"));
124 /// ```
125 #[cfg(all(feature = "json"))]
126 pub fn to_json(&self) -> Result<String, serde_json::Error> {
127 serde_json::to_string(&self)
128 }
129
130 /// Serialises the map to a JSON writer.
131 ///
132 /// Returns a `serde_json::Error` if the map cannot be serialised.
133 ///
134 /// # Examples
135 ///
136 /// ```
137 /// use anyval::Map;
138 ///
139 /// let mut map = Map::new();
140 /// map["key"] = "value".into();
141 /// let mut buffer = Vec::new();
142 /// map.to_json_writer(&mut buffer).unwrap();
143 /// assert_eq!(String::from_utf8(buffer).unwrap(), r#"{"key":"value"}"#);
144 /// ```
145 #[cfg(all(feature = "json"))]
146 pub fn to_json_writer<W: std::io::Write>(&self, writer: W) -> Result<(), serde_json::Error> {
147 serde_json::to_writer(writer, &self)
148 }
149}
150
151impl std::ops::Index<&str> for Map {
152 type Output = Value;
153
154 fn index(&self, index: &str) -> &Self::Output {
155 &self.inner[index]
156 }
157}
158
159impl std::ops::IndexMut<&str> for Map {
160 fn index_mut(&mut self, index: &str) -> &mut Self::Output {
161 self.inner
162 .entry(index.to_string())
163 .or_insert(Value::from(""))
164 }
165}
166
167impl std::ops::Deref for Map {
168 type Target = HashMap<String, Value>;
169
170 fn deref(&self) -> &Self::Target {
171 &self.inner
172 }
173}
174
175impl std::ops::DerefMut for Map {
176 fn deref_mut(&mut self) -> &mut Self::Target {
177 &mut self.inner
178 }
179}
180
181impl Default for Map {
182 fn default() -> Self {
183 Self::new()
184 }
185}
186/// A dynamically‑sized array that stores [`Value`] instances.
187///
188/// This type is a thin wrapper around `Vec<Value>` that provides a stable
189/// API for the rest of the crate. It implements `Debug` and `Clone` by
190/// delegating to the inner `Vec`.
191///
192/// # Examples
193///
194/// ```
195/// use anyval::{Array, Value};
196///
197/// let mut arr = Array::new();
198/// assert!(arr.is_empty());
199///
200/// arr.push(("something").into());
201/// assert!(!arr.is_empty());
202///
203/// // or using array macro
204/// use anyval::array;
205/// let arr2 = array!["value", 42, true];
206/// assert!(arr2[0].is_string());
207/// ```
208#[derive(Debug, Clone)]
209pub struct Array {
210 inner: Box<Vec<Value>>,
211}
212
213impl Array {
214 /// Creates a new, empty `Array`.
215 ///
216 /// The returned array does not allocate any memory until elements are
217 /// pushed onto it.
218 ///
219 /// # Examples
220 ///
221 /// ```
222 /// use anyval::Array;
223 ///
224 /// let mut arr = Array::new();
225 /// assert!(arr.is_empty());
226 /// arr.push((10).into());
227 /// assert_eq!(arr.len(), 1);
228 ///
229 /// ```
230 pub fn new() -> Self {
231 Self {
232 inner: Box::new(Vec::new()),
233 }
234 }
235
236 /// Creates an empty `Array` with at least the specified capacity.
237 ///
238 /// The array will be able to hold at least `capacity` elements without
239 /// reallocating. If `capacity` is 0, no allocation occurs.
240 ///
241 /// # Examples
242 ///
243 /// ```
244 /// use anyval::Array;
245 ///
246 /// let mut arr = Array::with_capacity(10);
247 /// assert_eq!(arr.capacity(), 10);
248 /// assert!(arr.is_empty());
249 /// ```
250 pub fn with_capacity(capacity: usize) -> Self {
251 Self {
252 inner: Box::new(Vec::with_capacity(capacity)),
253 }
254 }
255
256 #[cfg(all(feature = "json"))]
257 /// Deserialises a JSON string into an `Array`.
258 ///
259 /// Returns a `serde_json::Error` if the JSON cannot be parsed or does not
260 /// represent a valid array structure.
261 ///
262 /// # Examples
263 ///
264 /// ```
265 /// use anyval::Array;
266 ///
267 /// let json = r#"["value",42,true]"#;
268 /// let arr = Array::from_json(json).unwrap();
269 /// assert_eq!(arr[0].as_str(), "value");
270 /// assert_eq!(arr[1].as_int(), 42);
271 /// assert_eq!(arr[2].as_bool(), true);
272 /// ```
273 ///
274 /// # Nested example
275 ///
276 /// ```
277 /// use anyval::{Array, Value, Map};
278 ///
279 /// let json = r#"[{"key":"value"},42]"#;
280 /// let arr = Array::from_json(json).unwrap();
281 /// assert_eq!(arr[0].as_map().unwrap()["key"].as_str(), "value");
282 /// assert_eq!(arr[1].as_int(), 42);
283 /// ```
284 ///
285 pub fn from_json(s: &str) -> Result<Self, serde_json::Error> {
286 serde_json::from_str(s)
287 }
288
289 /// Serialises the array to a JSON string.
290 ///
291 /// Returns a `serde_json::Error` if the array cannot be serialised.
292 ///
293 /// # Examples
294 ///
295 /// ```
296 /// use anyval::Array;
297 ///
298 /// let mut arr = Array::new();
299 /// arr.push("value".into());
300 /// arr.push(42.into());
301 /// let json = arr.to_json().unwrap();
302 /// assert_eq!(json, r#"["value",42]"#);
303 /// ```
304 #[cfg(all(feature = "json"))]
305 pub fn to_json(&self) -> Result<String, serde_json::Error> {
306 serde_json::to_string(&self)
307 }
308
309 /// Serialises the array to a JSON writer.
310 ///
311 /// Returns a `serde_json::Error` if the array cannot be serialised.
312 ///
313 /// # Examples
314 ///
315 /// ```
316 /// use anyval::Array;
317 ///
318 /// let mut arr = Array::new();
319 /// arr.push("value".into());
320 /// arr.push(42.into());
321 /// let mut buffer = Vec::new();
322 /// arr.to_json_writer(&mut buffer).unwrap();
323 /// assert_eq!(String::from_utf8(buffer).unwrap(), r#"["value",42]"#);
324 /// ```
325 #[cfg(all(feature = "json"))]
326 pub fn to_json_writer<W: std::io::Write>(&self, writer: W) -> Result<(), serde_json::Error> {
327 serde_json::to_writer(writer, &self)
328 }
329}
330
331impl std::ops::Deref for Array {
332 type Target = Vec<Value>;
333
334 fn deref(&self) -> &Self::Target {
335 &self.inner
336 }
337}
338
339impl std::ops::DerefMut for Array {
340 fn deref_mut(&mut self) -> &mut Self::Target {
341 &mut self.inner
342 }
343}
344
345impl Default for Array {
346 fn default() -> Self {
347 Self::new()
348 }
349}
350
351/// A dynamically‑typed value used throughout the library.
352///
353/// This enum can represent the primitive scalar types supported by the
354/// library as well as compound collection types. It is deliberately
355/// exhaustive so that a `Value` can be stored in heterogeneous containers
356/// (e.g., maps or arrays) without losing type information.
357///
358/// # Variants
359///
360/// * **`Float(f64)`** – A 64‑bit floating‑point number. Mirrors the behaviour
361/// of `f64` in the Rust standard library, including `NaN` and `Infinity`
362/// handling.
363///
364/// * **`Int(i64)`** – A signed 64‑bit integer. Provides the full range of
365/// `i64` values.
366///
367/// * **`Bool(bool)`** – A boolean value, either `true` or `false`.
368///
369/// * **`String(Str)`** – A string value that may be a static slice, an
370/// `Arc<String>`, or an owned `String`. See [`Str`] for details.
371///
372/// * **`Map(Map)`** – An associative container mapping string keys to
373/// `Value`s. See [`Map`] for the underlying implementation.
374///
375/// * **`Array(Array)`** – An ordered list of `Value`s. See [`Array`] for the
376/// underlying implementation.
377///
378/// # Examples
379///
380/// ```rust
381/// # use anyval::Value;
382///
383/// let v = Value::from(3.14);
384/// assert!(matches!(v, Value::Float(_)));
385///
386/// let s = Value::from("hello");
387/// assert_eq!(s.as_str(), "hello");
388/// assert_eq!(v.as_str(), "3.14");
389/// ```
390pub enum Value {
391 /// 64‑bit floating‑point number.
392 Float(f64),
393
394 /// 64‑bit signed integer.
395 Int(i64),
396
397 /// Boolean value.
398 Bool(bool),
399
400 /// String value, using the library's flexible `Str` type.
401 String(Str),
402
403 /// Map (dictionary) of string keys to `Value`s.
404 Map(Map),
405
406 /// Array (list) of `Value`s.
407 Array(Array),
408
409 /// None value
410 None,
411}
412
413/// A borrowed reference to a `Value`.
414///
415/// This enum provides read‑only access to the data stored inside a `Value`
416/// without taking ownership. It mirrors the variants of `Value` but holds
417/// references (`&'a …`) to the underlying data, allowing inspection while
418/// preserving the original lifetime.
419///
420/// # Variants
421///
422/// * **`Float(&'a f64)`** – Reference to a 64‑bit floating‑point number.
423/// * **`Int(&'a i64)`** – Reference to a signed 64‑bit integer.
424/// * **`Bool(&'a bool)`** – Reference to a boolean value.
425/// * **`String(&'a Str)`** – Reference to a string (`Str`) value.
426/// * **`Map(&'a Map)`** – Reference to a map container.
427/// * **`Array(&'a Array)`** – Reference to an array container.
428/// * **`None`** – Represents the absence of a value.
429#[derive(Debug)]
430pub enum ValueRef<'a> {
431 /// Reference to a floating‑point number.
432 Float(&'a f64),
433 /// Reference to an integer.
434 Int(&'a i64),
435 /// Reference to a boolean.
436 Bool(&'a bool),
437 /// Reference to a string.
438 String(&'a Str),
439 /// Reference to a map.
440 Map(&'a Map),
441 /// Reference to an array.
442 Array(&'a Array),
443 /// No value.
444 None,
445}
446
447/// A mutable borrowed reference to a `Value`.
448///
449/// This enum provides write‑access to the data stored inside a `Value`
450/// via mutable references (`&'a mut …`). It mirrors the variants of
451/// `Value` but allows the underlying data to be modified in place.
452///
453/// # Variants
454///
455/// * **`Float(&'a mut f64)`** – Mutable reference to a floating‑point number.
456/// * **`Int(&'a mut i64)`** – Mutable reference to an integer.
457/// * **`Bool(&'a mut bool)`** – Mutable reference to a boolean.
458/// * **`String(&'a mut Str)`** – Mutable reference to a string.
459/// * **`Map(&'a mut Map)`** – Mutable reference to a map container.
460/// * **`Array(&'a mut Array)`** – Mutable reference to an array container.
461/// * **`None`** – Represents the absence of a value.
462#[derive(Debug)]
463pub enum ValueRefMut<'a> {
464 /// Mutable reference to a floating‑point number.
465 Float(&'a mut f64),
466 /// Mutable reference to an integer.
467 Int(&'a mut i64),
468 /// Mutable reference to a boolean.
469 Bool(&'a mut bool),
470 /// Mutable reference to a string.
471 String(&'a mut Str),
472 /// Mutable reference to a map.
473 Map(&'a mut Map),
474 /// Mutable reference to an array.
475 Array(&'a mut Array),
476 /// No value.
477 None,
478}
479
480impl Display for Value {
481 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
482 match self {
483 Value::String(s) => write!(f, "{}", s),
484 Value::Float(fl) => write!(f, "{}", fl),
485 Value::Int(i) => write!(f, "{}", i),
486 Value::Bool(b) => write!(f, "{}", b),
487 Value::Map(_) => write!(f, "[object Map]"),
488 Value::Array(_) => write!(f, "[object Array]"),
489 Value::None => write!(f, "null"),
490 }
491 }
492}
493
494impl Debug for Value {
495 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
496 match self {
497 Value::String(s) => write!(f, "{:?}", s),
498 Value::Float(fl) => write!(f, "Value::Float({:?})", fl),
499 Value::Int(i) => write!(f, "Value::Int({:?})", i),
500 Value::Bool(b) => write!(f, "Value::Bool({:?})", b),
501 Value::Map(m) => write!(f, "Value::Map({:?})", m),
502 Value::Array(a) => write!(f, "Value::Array({:?})", a),
503 Value::None => write!(f, "Value::None"),
504 }
505 }
506}
507
508impl Clone for Value {
509 fn clone(&self) -> Self {
510 match self {
511 Value::String(s) => Value::String(s.clone()),
512 Value::Float(fl) => Value::Float(*fl),
513 Value::Int(i) => Value::Int(*i),
514 Value::Bool(b) => Value::Bool(*b),
515 Value::Map(m) => Value::Map(m.clone()),
516 Value::Array(a) => Value::Array(a.clone()),
517 Value::None => Value::None,
518 }
519 }
520}
521impl Value {
522 /// Creates a `Value` from any type that implements `Into<Value>`.
523 /// ///
524 /// This is a convenience method that allows for easy conversion of
525 /// common types into `Value` instances.
526 ///
527 /// # Examples
528 ///
529 /// ```
530 /// # use anyval::Value;
531 /// let v_float = Value::from(3.14);
532 /// let v_int = Value::from(42);
533 /// let v_bool = Value::from(true);
534 /// let v_string = Value::from("hello");
535 /// assert!(matches!(v_float, Value::Float(_)));
536 /// assert!(matches!(v_int, Value::Int(_)));
537 /// assert!(matches!(v_bool, Value::Bool(_)));
538 /// assert!(matches!(v_string, Value::String(_)));
539 /// ```
540 pub fn from<T: Into<Value>>(value: T) -> Self {
541 value.into()
542 }
543
544 /// Returns a string representation of the value.
545 ///
546 /// If the value is a `String`, a borrowed `&str` is returned.
547 /// Otherwise the value is formatted with `to_string()` and an owned
548 /// `String` is returned inside a `Cow::Owned`.
549 ///
550 /// # Examples
551 ///
552 /// ```
553 /// # use anyval::{Value, Str};
554 /// let v = Value::String(Str::from_static("hello"));
555 /// assert_eq!(v.as_str(), "hello");
556 ///
557 /// let v = Value::Int(42);
558 /// assert_eq!(v.as_str(), "42");
559 /// ```
560 pub fn as_str(&self) -> Cow<'_, str> {
561 match self {
562 Value::String(s) => Cow::Borrowed(s.as_str()),
563 _ => Cow::Owned(self.to_string()),
564 }
565 }
566
567 /// Attempts to interpret the value as a 64‑bit floating‑point number.
568 ///
569 /// The conversion rules are:
570 ///
571 /// * `Float` – returns the contained `f64`.
572 /// * `Int` – casts the integer to `f64`.
573 /// * `String` – parses the string as `f64`; on parse failure `0.0` is returned.
574 /// * `Bool` – `true` becomes `1.0`, `false` becomes `0.0`.
575 /// * Any other variant – returns `0.0`.
576 ///
577 /// # Examples
578 ///
579 /// ```
580 /// # use anyval::Value;
581 /// assert_eq!(Value::Float(3.14).as_float(), 3.14);
582 /// assert_eq!(Value::Int(2).as_float(), 2.0);
583 /// assert_eq!(Value::Bool(true).as_float(), 1.0);
584 /// assert_eq!(Value::String("2.5".into()).as_float(), 2.5);
585 /// ```
586 pub fn as_float(&self) -> f64 {
587 match self {
588 Value::Float(f) => *f,
589 Value::Int(i) => *i as f64,
590 Value::String(str) => str.as_str().parse::<f64>().unwrap_or(0.0),
591 Value::Bool(b) => {
592 if *b {
593 1.0
594 } else {
595 0.0
596 }
597 }
598 _ => 0.0,
599 }
600 }
601
602 /// Attempts to interpret the value as a signed 64‑bit integer.
603 ///
604 /// The conversion rules are:
605 ///
606 /// * `Int` – returns the contained integer.
607 /// * `Float` – truncates the floating‑point value.
608 /// * `String` – parses the string as `i64`; on parse failure `0` is returned.
609 /// * `Bool` – `true` becomes `1`, `false` becomes `0`.
610 /// * Any other variant – returns `0`.
611 ///
612 /// # Examples
613 ///
614 /// ```
615 /// # use anyval::Value;
616 /// assert_eq!(Value::Int(7).as_int(), 7);
617 /// assert_eq!(Value::Float(3.9).as_int(), 3);
618 /// assert_eq!(Value::Bool(false).as_int(), 0);
619 /// assert_eq!(Value::String("42".into()).as_int(), 42);
620 /// ```
621 pub fn as_int(&self) -> i64 {
622 match self {
623 Value::Int(i) => *i,
624 Value::Float(f) => *f as i64,
625 Value::String(str) => str.as_str().parse::<i64>().unwrap_or(0),
626 Value::Bool(b) => {
627 if *b {
628 1
629 } else {
630 0
631 }
632 }
633 _ => 0,
634 }
635 }
636
637 /// Returns the boolean representation of the value.
638 ///
639 /// Conversion rules:
640 ///
641 /// * `Bool` – returns the contained boolean.
642 /// * `Int` – `0` is `false`, any other integer is `true`.
643 /// * `Float` – `0.0` is `false`, any other number is `true`.
644 /// * `String` – empty string is `false`, otherwise `true`.
645 /// * `Map` / `Array` – empty collections are `false`, otherwise `true`.
646 ///
647 /// # Examples
648 ///
649 /// ```
650 /// # use anyval::{Value, Map, Array};
651 /// assert!(Value::Bool(true).as_bool());
652 /// assert!(!Value::Int(0).as_bool());
653 /// assert!(Value::String("text".into()).as_bool());
654 /// ```
655 pub fn as_bool(&self) -> bool {
656 match self {
657 Value::Bool(b) => *b,
658 Value::Int(i) => *i != 0,
659 Value::Float(f) => *f != 0.0,
660 Value::String(s) => !s.as_str().is_empty(),
661 Value::Map(m) => !m.is_empty(),
662 Value::Array(a) => !a.is_empty(),
663 Value::None => false,
664 }
665 }
666
667 /// Returns a reference to the underlying map if the value is a `Map`.
668 ///
669 /// # Returns
670 ///
671 /// * `Some(&Map)` – when the variant is `Value::Map`.
672 /// * `None` – for all other variants.
673 ///
674 /// # Examples
675 ///
676 /// ```
677 /// # use anyval::{Value, Map};
678 /// let map = Map::new();
679 /// let v = Value::Map(map);
680 /// assert!(v.as_map().is_some());
681 /// ```
682 pub fn as_map(&self) -> Option<&Map> {
683 match self {
684 Value::Map(m) => Some(m),
685 _ => None,
686 }
687 }
688
689 /// Returns a reference to the underlying array if the value is an `Array`.
690 ///
691 /// # Returns
692 ///
693 /// * `Some(&Array)` – when the variant is `Value::Array`.
694 /// * `None` – for all other variants.
695 ///
696 /// # Examples
697 ///
698 /// ```
699 /// # use anyval::{Value, Array};
700 /// let arr = Array::new();
701 /// let v = Value::Array(arr);
702 /// assert!(v.as_array().is_some());
703 /// ```
704 pub fn as_array(&self) -> Option<&Array> {
705 match self {
706 Value::Array(a) => Some(a),
707 _ => None,
708 }
709 }
710
711 /// Returns `true` if the value is a `Float`.
712 pub fn is_float(&self) -> bool {
713 matches!(self, Value::Float(_))
714 }
715
716 /// Returns `true` if the value is an `Int`.
717 pub fn is_int(&self) -> bool {
718 matches!(self, Value::Int(_))
719 }
720
721 /// Returns `true` if the value is a `Bool`.
722 pub fn is_bool(&self) -> bool {
723 matches!(self, Value::Bool(_))
724 }
725
726 /// Returns `true` if the value is a `String`.
727 pub fn is_string(&self) -> bool {
728 matches!(self, Value::String(_))
729 }
730
731 /// Returns `true` if the value is a `Map`.
732 pub fn is_map(&self) -> bool {
733 matches!(self, Value::Map(_))
734 }
735
736 /// Returns `true` if the value is an `Array`.
737 pub fn is_array(&self) -> bool {
738 matches!(self, Value::Array(_))
739 }
740
741 /// Creates a new empty `Value::Map`.
742 pub fn new_map() -> Self {
743 Value::Map(Map::new())
744 }
745
746 /// Creates a new empty `Value::Array`.
747 pub fn new_array() -> Self {
748 Value::Array(Array::new())
749 }
750
751 /// Safely gets a value from a map by key, returning None if not a map or key doesn't exist
752 pub fn get(&self, key: &str) -> Option<&Value> {
753 self.as_map()?.get(key)
754 }
755
756 /// Safely gets a value from an array by index
757 pub fn get_index(&self, index: usize) -> Option<&Value> {
758 self.as_array()?.get(index)
759 }
760
761 #[cfg(all(feature = "json"))]
762 /// Deserialises a JSON string into a `Value`.
763 ///
764 /// Returns a `serde_json::Error` if the JSON cannot be parsed.
765 ///
766 /// # Examples
767 ///
768 /// ```
769 /// use anyval::Value;
770 ///
771 /// let json = r#"{"key":"value","num":42}"#;
772 /// let val = Value::from_json(json).unwrap();
773 /// assert_eq!(val["key"].as_str(), "value");
774 /// assert_eq!(val["num"].as_int(), 42);
775 /// ```
776 ///
777 /// # Array example
778 ///
779 /// ```
780 /// use anyval::Value;
781 ///
782 /// let json = r#"["value",42,true]"#;
783 /// let val = Value::from_json(json).unwrap();
784 /// assert_eq!(val[0].as_str(), "value");
785 /// assert_eq!(val[1].as_int(), 42);
786 /// assert_eq!(val[2].as_bool(), true);
787 /// ```
788 pub fn from_json(s: &str) -> Result<Self, serde_json::Error> {
789 serde_json::from_str(s)
790 }
791
792 /// Serialises the value to a JSON string.
793 ///
794 /// Returns a `serde_json::Error` if the value cannot be serialised.
795 ///
796 /// # Examples
797 ///
798 /// ```
799 /// use anyval::Value;
800 ///
801 /// let val = Value::from("hello");
802 /// let json = val.to_json().unwrap();
803 /// assert_eq!(json, r#""hello""#);
804 /// ```
805 ///
806 /// # Map example
807 ///
808 /// ```
809 /// use anyval::{Value, Map};
810 ///
811 /// let mut map = Map::new();
812 /// map["key"] = "value".into();
813 /// let val = Value::Map(map);
814 /// let json = val.to_json().unwrap();
815 /// assert_eq!(json, r#"{"key":"value"}"#);
816 /// ```
817 #[cfg(all(feature = "json"))]
818 pub fn to_json(&self) -> Result<String, serde_json::Error> {
819 serde_json::to_string(&self)
820 }
821
822 /// Serialises the value to a JSON writer.
823 ///
824 /// Returns a `serde_json::Error` if the value cannot be serialised.
825 ///
826 /// # Examples
827 ///
828 /// ```
829 /// use anyval::Value;
830 ///
831 /// let val = Value::from(42);
832 /// let mut buffer = Vec::new();
833 /// val.to_json_writer(&mut buffer).unwrap();
834 /// assert_eq!(String::from_utf8(buffer).unwrap(), "42");
835 /// ```
836 #[cfg(all(feature = "json"))]
837 pub fn to_json_writer<W: std::io::Write>(&self, writer: W) -> Result<(), serde_json::Error> {
838 serde_json::to_writer(writer, &self)
839 }
840}
841
842#[cfg(feature = "serde")]
843impl Serialize for Value {
844 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
845 where
846 S: serde::Serializer,
847 {
848 match self {
849 Value::Float(f) => serializer.serialize_f64(*f),
850 Value::Int(i) => serializer.serialize_i64(*i),
851 Value::Bool(b) => serializer.serialize_bool(*b),
852 Value::String(s) => serializer.serialize_str(s.as_str()),
853 Value::Map(m) => m.inner.serialize(serializer),
854 Value::Array(a) => a.inner.serialize(serializer),
855 Value::None => serializer.serialize_none(),
856 }
857 }
858}
859
860impl std::ops::Index<&str> for Value {
861 type Output = Value;
862
863 fn index(&self, index: &str) -> &Self::Output {
864 match self {
865 Value::Map(m) => &m[index],
866 _ => &Value::None,
867 }
868 }
869}
870
871impl std::ops::IndexMut<&str> for Value {
872 fn index_mut(&mut self, index: &str) -> &mut Self::Output {
873 match self {
874 Value::Map(m) => &mut m[index],
875 _ => {
876 *self = Value::None;
877 self
878 }
879 }
880 }
881}
882
883impl std::ops::Index<usize> for Value {
884 type Output = Value;
885
886 fn index(&self, index: usize) -> &Self::Output {
887 match self {
888 Value::Array(a) => &a[index],
889 _ => &Value::None,
890 }
891 }
892}
893
894impl std::ops::IndexMut<usize> for Value {
895 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
896 match self {
897 Value::Array(a) => &mut a[index],
898 _ => {
899 *self = Value::None;
900 self
901 }
902 }
903 }
904}
905
906#[cfg(feature = "serde")]
907impl<'de> Deserialize<'de> for Value {
908 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
909 where
910 D: serde::Deserializer<'de>,
911 {
912 struct ValueVisitor;
913
914 impl<'de> serde::de::Visitor<'de> for ValueVisitor {
915 type Value = Value;
916
917 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
918 formatter.write_str("a valid Value")
919 }
920
921 fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
922 where
923 E: serde::de::Error,
924 {
925 Ok(Value::Float(v))
926 }
927
928 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
929 where
930 E: serde::de::Error,
931 {
932 Ok(Value::Int(v))
933 }
934
935 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
936 where
937 E: serde::de::Error,
938 {
939 Ok(Value::Bool(v))
940 }
941
942 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
943 where
944 E: serde::de::Error,
945 {
946 Ok(Value::String(Str::from_owned(v.to_string())))
947 }
948
949 fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
950 where
951 E: serde::de::Error,
952 {
953 self.visit_i64(v as i64)
954 }
955
956 fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
957 where
958 E: serde::de::Error,
959 {
960 self.visit_i64(v as i64)
961 }
962
963 fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
964 where
965 E: serde::de::Error,
966 {
967 self.visit_i64(v as i64)
968 }
969
970 fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
971 where
972 E: serde::de::Error,
973 {
974 let mut writer = String::new();
975 std::fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as i128", v))
976 .unwrap();
977 Err(serde::de::Error::invalid_type(
978 serde::de::Unexpected::Other(writer.as_str()),
979 &self,
980 ))
981 }
982
983 fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
984 where
985 E: serde::de::Error,
986 {
987 self.visit_i64(v as i64)
988 }
989
990 fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
991 where
992 E: serde::de::Error,
993 {
994 self.visit_i64(v as i64)
995 }
996
997 fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
998 where
999 E: serde::de::Error,
1000 {
1001 self.visit_i64(v as i64)
1002 }
1003
1004 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
1005 where
1006 E: serde::de::Error,
1007 {
1008 if v <= i64::MAX as u64 {
1009 Ok(Value::Int(v as i64))
1010 } else {
1011 Ok(Value::Float(v as f64))
1012 }
1013 }
1014
1015 fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
1016 where
1017 E: serde::de::Error,
1018 {
1019 // If the value fits into an i64, store it as an integer.
1020 if v <= i64::MAX as u128 {
1021 Ok(Value::Int(v as i64))
1022 } else {
1023 // Otherwise fall back to a floating‑point representation.
1024 Ok(Value::Float(v as f64))
1025 }
1026 }
1027 fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
1028 where
1029 E: serde::de::Error,
1030 {
1031 self.visit_f64(v as f64)
1032 }
1033
1034 fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
1035 where
1036 E: serde::de::Error,
1037 {
1038 self.visit_str(v.encode_utf8(&mut [0u8; 4]))
1039 }
1040
1041 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
1042 where
1043 E: serde::de::Error,
1044 {
1045 self.visit_str(v)
1046 }
1047
1048 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
1049 where
1050 E: serde::de::Error,
1051 {
1052 self.visit_str(&v)
1053 }
1054
1055 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
1056 where
1057 E: serde::de::Error,
1058 {
1059 Err(serde::de::Error::invalid_type(
1060 serde::de::Unexpected::Bytes(v),
1061 &self,
1062 ))
1063 }
1064
1065 fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
1066 where
1067 E: serde::de::Error,
1068 {
1069 self.visit_bytes(v)
1070 }
1071
1072 fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
1073 where
1074 E: serde::de::Error,
1075 {
1076 self.visit_bytes(&v)
1077 }
1078
1079 fn visit_none<E>(self) -> Result<Self::Value, E>
1080 where
1081 E: serde::de::Error,
1082 {
1083 Ok(Value::None)
1084 }
1085
1086 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1087 where
1088 D: serde::Deserializer<'de>,
1089 {
1090 let _ = deserializer;
1091 Err(serde::de::Error::invalid_type(
1092 serde::de::Unexpected::Option,
1093 &self,
1094 ))
1095 }
1096
1097 fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
1098 where
1099 A: serde::de::MapAccess<'de>,
1100 {
1101 let inner = Map::deserialize(serde::de::value::MapAccessDeserializer::new(map))?;
1102 Ok(Value::Map(inner))
1103 }
1104
1105 fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
1106 where
1107 A: serde::de::SeqAccess<'de>,
1108 {
1109 let inner = Array::deserialize(serde::de::value::SeqAccessDeserializer::new(seq))?;
1110 Ok(Value::Array(inner))
1111 }
1112 }
1113
1114 deserializer.deserialize_any(ValueVisitor)
1115 }
1116}
1117
1118#[cfg(feature = "serde")]
1119impl Serialize for Map {
1120 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1121 where
1122 S: serde::Serializer,
1123 {
1124 self.inner.serialize(serializer)
1125 }
1126}
1127
1128#[cfg(feature = "serde")]
1129impl<'de> Deserialize<'de> for Map {
1130 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1131 where
1132 D: serde::Deserializer<'de>,
1133 {
1134 let inner = Box::new(HashMap::deserialize(deserializer)?);
1135 Ok(Map { inner })
1136 }
1137}
1138
1139#[cfg(feature = "serde")]
1140impl Serialize for Array {
1141 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1142 where
1143 S: serde::Serializer,
1144 {
1145 self.inner.serialize(serializer)
1146 }
1147}
1148
1149#[cfg(feature = "serde")]
1150impl<'de> Deserialize<'de> for Array {
1151 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1152 where
1153 D: serde::Deserializer<'de>,
1154 {
1155 let inner = Box::new(Vec::<Value>::deserialize(deserializer)?);
1156 Ok(Array { inner })
1157 }
1158}
1159
1160// From implementations for Value
1161impl From<f64> for Value {
1162 fn from(f: f64) -> Self {
1163 Value::Float(f)
1164 }
1165}
1166
1167impl From<i64> for Value {
1168 fn from(i: i64) -> Self {
1169 Value::Int(i)
1170 }
1171}
1172
1173impl From<bool> for Value {
1174 fn from(b: bool) -> Self {
1175 Value::Bool(b)
1176 }
1177}
1178
1179impl From<Map> for Value {
1180 fn from(m: Map) -> Self {
1181 Value::Map(m)
1182 }
1183}
1184
1185impl From<Array> for Value {
1186 fn from(a: Array) -> Self {
1187 Value::Array(a)
1188 }
1189}
1190
1191impl From<i32> for Value {
1192 fn from(i: i32) -> Self {
1193 Value::Int(i as i64)
1194 }
1195}
1196
1197impl From<i128> for Value {
1198 fn from(i: i128) -> Self {
1199 if i <= i64::MAX as i128 && i >= i64::MIN as i128 {
1200 Value::Int(i as i64)
1201 } else {
1202 Value::Float(i as f64)
1203 }
1204 }
1205}
1206
1207impl From<u64> for Value {
1208 fn from(u: u64) -> Self {
1209 if u <= i64::MAX as u64 {
1210 Value::Int(u as i64)
1211 } else {
1212 Value::Float(u as f64)
1213 }
1214 }
1215}
1216
1217impl From<u128> for Value {
1218 fn from(u: u128) -> Self {
1219 if u <= i64::MAX as u128 {
1220 Value::Int(u as i64)
1221 } else {
1222 Value::Float(u as f64)
1223 }
1224 }
1225}
1226
1227impl From<f32> for Value {
1228 fn from(f: f32) -> Self {
1229 Value::Float(f as f64)
1230 }
1231}
1232
1233impl Into<f64> for Value {
1234 fn into(self) -> f64 {
1235 self.as_float()
1236 }
1237}
1238
1239impl Into<i8> for Value {
1240 fn into(self) -> i8 {
1241 self.as_int() as i8
1242 }
1243}
1244
1245impl Into<i16> for Value {
1246 fn into(self) -> i16 {
1247 self.as_int() as i16
1248 }
1249}
1250
1251impl Into<i32> for Value {
1252 fn into(self) -> i32 {
1253 self.as_int() as i32
1254 }
1255}
1256
1257impl Into<i64> for Value {
1258 fn into(self) -> i64 {
1259 self.as_int()
1260 }
1261}
1262
1263impl Into<i128> for Value {
1264 fn into(self) -> i128 {
1265 self.as_int() as i128
1266 }
1267}
1268
1269impl Into<isize> for Value {
1270 fn into(self) -> isize {
1271 self.as_int() as isize
1272 }
1273}
1274
1275impl Into<usize> for Value {
1276 fn into(self) -> usize {
1277 self.as_int() as usize
1278 }
1279}
1280
1281impl Into<bool> for Value {
1282 fn into(self) -> bool {
1283 self.as_bool()
1284 }
1285}
1286
1287impl From<&String> for Value {
1288 fn from(s: &String) -> Self {
1289 Value::String(Str::from_owned(s.clone()))
1290 }
1291}
1292
1293impl TryFrom<Value> for String {
1294 type Error = &'static str;
1295
1296 fn try_from(value: Value) -> Result<Self, Self::Error> {
1297 match value {
1298 Value::String(s) => Ok(s.to_string()),
1299 _ => Err("Value is not a string"),
1300 }
1301 }
1302}
1303
1304// Add PartialEq for Value comparison
1305impl PartialEq for Value {
1306 fn eq(&self, other: &Self) -> bool {
1307 match (self, other) {
1308 (Value::Float(a), Value::Float(b)) => a == b,
1309 (Value::Int(a), Value::Int(b)) => a == b,
1310 (Value::Bool(a), Value::Bool(b)) => a == b,
1311 (Value::String(a), Value::String(b)) => a.as_str() == b.as_str(),
1312 (Value::None, Value::None) => true,
1313 // Cross-type numeric comparisons
1314 (Value::Float(f), Value::Int(i)) | (Value::Int(i), Value::Float(f)) => *f == *i as f64,
1315 _ => false,
1316 }
1317 }
1318}
1319
1320// Add IntoIterator for Array
1321impl IntoIterator for Array {
1322 type Item = Value;
1323 type IntoIter = std::vec::IntoIter<Value>;
1324
1325 fn into_iter(self) -> Self::IntoIter {
1326 self.inner.into_iter()
1327 }
1328}
1329
1330impl<'a> IntoIterator for &'a Array {
1331 type Item = &'a Value;
1332 type IntoIter = std::slice::Iter<'a, Value>;
1333
1334 fn into_iter(self) -> Self::IntoIter {
1335 self.inner.iter()
1336 }
1337}
1338
1339// Add helper methods to Value
1340impl Value {
1341 /// Returns a mutable reference to the underlying map if the value is a `Map`.
1342 pub fn as_map_mut(&mut self) -> Option<&mut Map> {
1343 match self {
1344 Value::Map(m) => Some(m),
1345 _ => None,
1346 }
1347 }
1348
1349 /// Returns a mutable reference to the underlying array if the value is an `Array`.
1350 pub fn as_array_mut(&mut self) -> Option<&mut Array> {
1351 match self {
1352 Value::Array(a) => Some(a),
1353 _ => None,
1354 }
1355 }
1356
1357 /// Returns `true` if the value is `None`.
1358 pub fn is_none(&self) -> bool {
1359 matches!(self, Value::None)
1360 }
1361
1362 /// Takes the value out, leaving `Value::None` in its place.
1363 pub fn take(&mut self) -> Value {
1364 std::mem::replace(self, Value::None)
1365 }
1366}
1367
1368// Add FromIterator for Array
1369impl FromIterator<Value> for Array {
1370 fn from_iter<T: IntoIterator<Item = Value>>(iter: T) -> Self {
1371 Array {
1372 inner: Box::new(iter.into_iter().collect()),
1373 }
1374 }
1375}
1376
1377// Add FromIterator for Map
1378impl FromIterator<(String, Value)> for Map {
1379 fn from_iter<T: IntoIterator<Item = (String, Value)>>(iter: T) -> Self {
1380 Map {
1381 inner: Box::new(iter.into_iter().collect()),
1382 }
1383 }
1384}
1385
1386/// Creates a [`Map`] containing the given key-value pairs.
1387///
1388/// This macro provides a convenient way to initialize a `Map` with known entries.
1389/// It comes in two forms:
1390///
1391/// # Forms
1392///
1393/// - `map!()` - Creates an empty map
1394/// - `map!(key => value, ...)` - Creates a map with the specified key-value pairs
1395///
1396/// # Examples
1397///
1398/// ```
1399/// # use anyval::map;
1400/// // Create an empty map
1401/// let empty = map!();
1402///
1403/// // Create a map with initial values
1404/// let m = map! {
1405/// "name" => "Alice",
1406/// "age" => 30,
1407/// "active" => true,
1408/// };
1409/// ```
1410///
1411/// # Notes
1412///
1413/// - Keys are used directly without conversion
1414/// - Values are converted using `.into()` to support flexible value types
1415/// - The map is pre-allocated with the exact capacity needed
1416/// - Trailing commas are allowed
1417#[macro_export]
1418macro_rules! map {
1419 () => {
1420 $crate::Map::new()
1421 };
1422 ($($key:expr => $val:expr),* $(,)?) => {{
1423 let mut m = $crate::Map::with_capacity(count_tts::count_tts!($($key)*));
1424 $(
1425 m[$key] = $val.into();
1426 )*
1427 m
1428 }};
1429}
1430
1431/// Creates an [`Array`] containing the given values.
1432///
1433/// This macro provides a convenient way to create an `Array` with initial values,
1434/// similar to the `vec!` macro for `Vec`.
1435///
1436/// # Examples
1437///
1438/// ```
1439/// # use anyval::array;
1440/// // Create an empty array
1441/// let empty = array![];
1442///
1443/// // Create an array with values
1444/// let numbers = array![1, 2, 3, 4, 5];
1445///
1446/// // Trailing commas are allowed
1447/// let mixed = array![
1448/// "hello",
1449/// 42,
1450/// true,
1451/// ];
1452/// ```
1453///
1454/// # Notes
1455///
1456/// - Values are automatically converted using `.into()`, so they must implement
1457/// the appropriate `Into` trait for the array's element type.
1458/// - The capacity is pre-allocated to match the number of elements when known at
1459/// compile time.
1460#[macro_export]
1461macro_rules! array {
1462 () => {
1463 $crate::Array::new()
1464 };
1465 ($($val:expr),* $(,)?) => {{
1466 let mut a = $crate::Array::with_capacity(count_tts::count_tts!($($val)*));
1467 $(
1468 a.push($val.into());
1469 )*
1470 a
1471 }};
1472}
1473
1474#[cfg(test)]
1475mod tests {
1476 use super::*;
1477
1478 #[test]
1479 fn test_map_macro_empty() {
1480 let m = map! {};
1481 assert_eq!(m.len(), 0);
1482 }
1483
1484 #[test]
1485 fn test_map_macro_single_entry() {
1486 let m = map! {
1487 "key" => "value"
1488 };
1489 assert_eq!(m.len(), 1);
1490 assert_eq!(m["key"].as_str(), "value");
1491 }
1492
1493 #[test]
1494 fn test_map_macro_multiple_entries() {
1495 let m = map! {
1496 "name" => "Alice",
1497 "age" => 30,
1498 "active" => true,
1499 };
1500 assert_eq!(m.len(), 3);
1501 assert_eq!(m["name"].as_str(), "Alice");
1502 assert_eq!(m["age"].as_int(), 30);
1503 assert_eq!(m["active"].as_bool(), true);
1504 }
1505
1506 #[test]
1507 fn test_map_macro_mixed_types() {
1508 let m = map! {
1509 "float" => 3.14,
1510 "int" => 42,
1511 "bool" => false,
1512 "string" => "hello",
1513 };
1514 assert_eq!(m["float"].as_float(), 3.14);
1515 assert_eq!(m["int"].as_int(), 42);
1516 assert_eq!(m["bool"].as_bool(), false);
1517 assert_eq!(m["string"].as_str(), "hello");
1518 }
1519
1520 #[test]
1521 fn test_map_macro_nested() {
1522 let inner = map! {
1523 "inner_key" => "inner_value"
1524 };
1525 let m = map! {
1526 "outer" => Value::Map(inner)
1527 };
1528 assert_eq!(m["outer"]["inner_key"].as_str(), "inner_value");
1529 }
1530
1531 #[test]
1532 fn test_array_macro_empty() {
1533 let a = array![];
1534 assert_eq!(a.len(), 0);
1535 }
1536
1537 #[test]
1538 fn test_array_macro_single_element() {
1539 let a = array![42];
1540 assert_eq!(a.len(), 1);
1541 assert_eq!(a[0].as_int(), 42);
1542 }
1543
1544 #[test]
1545 fn test_array_macro_multiple_elements() {
1546 let a = array![1, 2, 3, 4, 5];
1547 assert_eq!(a.len(), 5);
1548 assert_eq!(a[0].as_int(), 1);
1549 assert_eq!(a[4].as_int(), 5);
1550 }
1551
1552 #[test]
1553 fn test_array_macro_mixed_types() {
1554 let a = array!["hello", 42, true, 3.14];
1555 assert_eq!(a.len(), 4);
1556 assert_eq!(a[0].as_str(), "hello");
1557 assert_eq!(a[1].as_int(), 42);
1558 assert_eq!(a[2].as_bool(), true);
1559 assert_eq!(a[3].as_float(), 3.14);
1560 }
1561
1562 #[test]
1563 fn test_array_macro_trailing_comma() {
1564 let a = array![1, 2, 3,];
1565 assert_eq!(a.len(), 3);
1566 }
1567
1568 #[test]
1569 fn test_array_macro_nested() {
1570 let inner = array![1, 2, 3];
1571 let a = array![Value::Array(inner), 42];
1572 assert_eq!(a.len(), 2);
1573 assert_eq!(a[0][0].as_int(), 1);
1574 assert_eq!(a[1].as_int(), 42);
1575 }
1576
1577 #[test]
1578 fn test_map_macro_with_array_values() {
1579 let arr = array![1, 2, 3];
1580 let m = map! {
1581 "numbers" => Value::Array(arr)
1582 };
1583 assert_eq!(m["numbers"][0].as_int(), 1);
1584 }
1585
1586 #[test]
1587 fn test_array_macro_with_map_values() {
1588 let m = map! {
1589 "key" => "value"
1590 };
1591 let a = array![Value::Map(m), "other"];
1592 assert_eq!(a[0]["key"].as_str(), "value");
1593 assert_eq!(a[1].as_str(), "other");
1594 }
1595
1596 #[test]
1597 fn test_complex_nested_structure() {
1598 let m = map! {
1599 "users" => array! [
1600 map! {
1601 "name" => "Alice",
1602 "age" => 30
1603 },
1604 map! {
1605 "name" => "Bob",
1606 "age" => 25
1607 }
1608 ],
1609 "count" => 2
1610 };
1611 assert_eq!(m["users"][0]["name"].as_str(), "Alice");
1612 assert_eq!(m["users"][1]["age"].as_int(), 25);
1613 assert_eq!(m["count"].as_int(), 2);
1614 }
1615}