Skip to main content

regorus/
value.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#![allow(
5    clippy::indexing_slicing,
6    clippy::shadow_unrelated,
7    clippy::option_if_let_else,
8    clippy::semicolon_if_nothing_returned,
9    clippy::pattern_type_mismatch,
10    clippy::unused_trait_names,
11    clippy::as_conversions
12)] // value helpers index paths directly for performance
13
14use crate::number::Number;
15
16use alloc::{
17    collections::{BTreeMap, BTreeSet},
18    vec::Vec,
19};
20use core::{fmt, ops};
21
22use core::{convert::AsRef, str::FromStr};
23
24use anyhow::{anyhow, bail, Result};
25use serde::{
26    de::{self, Deserializer, Error as DeError, MapAccess, SeqAccess, Visitor},
27    ser::{SerializeMap, Serializer},
28    Deserialize, Serialize,
29};
30
31use crate::*;
32
33/// A value in a Rego document.
34///
35/// Value is similar to a [`serde_json::value::Value`], but has the following additional
36/// capabilities:
37///    - [`Value::Set`] variant to represent sets.
38///    - [`Value::Undefined`] variant to represent absence of value.
39//     - [`Value::Object`] keys can be other values, not just strings.
40///    - [`Value::Number`] has at least 100 digits of precision for computations.
41///
42/// Value can be efficiently cloned due to the use of reference counting.
43#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
44pub enum Value {
45    /// JSON null.
46    Null,
47
48    /// JSON boolean.
49    Bool(bool),
50
51    /// JSON number.
52    /// At least 100 digits of precision.
53    Number(Number),
54
55    /// JSON string.
56    String(Rc<str>),
57
58    /// JSON array.
59    Array(Rc<Vec<Value>>),
60
61    /// A set of values.
62    /// No JSON equivalent.
63    /// Sets are serialized as arrays in JSON.
64    Set(Rc<BTreeSet<Value>>),
65
66    /// An object.
67    /// Unlike JSON, keys can be any value, not just string.
68    Object(Rc<BTreeMap<Value, Value>>),
69
70    /// Undefined value.
71    /// Used to indicate the absence of a value.
72    Undefined,
73}
74
75#[inline]
76fn enforce_limit_anyhow() -> Result<()> {
77    crate::utils::limits::check_memory_limit_if_needed().map_err(|err| anyhow!(err))
78}
79
80#[inline]
81fn enforce_limit_for<E: DeError>() -> core::result::Result<(), E> {
82    crate::utils::limits::check_memory_limit_if_needed().map_err(|err| E::custom(err.to_string()))
83}
84
85#[doc(hidden)]
86impl Serialize for Value {
87    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
88    where
89        S: Serializer,
90    {
91        use serde::ser::Error;
92        match self {
93            Value::Null => serializer.serialize_unit(),
94            Value::Bool(b) => serializer.serialize_bool(*b),
95            Value::String(s) => serializer.serialize_str(s.as_ref()),
96            Value::Number(n) => n.serialize(serializer),
97            Value::Array(a) => a.serialize(serializer),
98            Value::Object(fields) => {
99                let mut map = serializer.serialize_map(Some(fields.len()))?;
100                for (k, v) in fields.iter() {
101                    match k {
102                        Value::String(_) => map.serialize_entry(k, v)?,
103                        _ => {
104                            let key_str = serde_json::to_string(k).map_err(Error::custom)?;
105                            map.serialize_entry(&key_str, v)?
106                        }
107                    }
108                }
109                map.end()
110            }
111
112            // display set as an array
113            Value::Set(s) => s.serialize(serializer),
114
115            // display undefined as a special string
116            Value::Undefined => serializer.serialize_str("<undefined>"),
117        }
118    }
119}
120
121struct ValueVisitor;
122
123impl<'de> Visitor<'de> for ValueVisitor {
124    type Value = Value;
125
126    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
127        formatter.write_str("a value")
128    }
129
130    fn visit_unit<E>(self) -> Result<Self::Value, E>
131    where
132        E: de::Error,
133    {
134        Ok(Value::Null)
135    }
136
137    fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
138    where
139        E: de::Error,
140    {
141        Ok(Value::Bool(v))
142    }
143
144    fn visit_none<E>(self) -> Result<Self::Value, E>
145    where
146        E: de::Error,
147    {
148        Ok(Value::Null)
149    }
150
151    fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
152    where
153        D: Deserializer<'de>,
154    {
155        Value::deserialize(deserializer)
156    }
157
158    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
159    where
160        E: de::Error,
161    {
162        Ok(Value::from(v))
163    }
164
165    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
166    where
167        E: de::Error,
168    {
169        Ok(Value::from(v))
170    }
171
172    fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
173    where
174        E: de::Error,
175    {
176        Ok(Value::from(v))
177    }
178
179    fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
180    where
181        E: de::Error,
182    {
183        Ok(Value::from(v))
184    }
185
186    fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
187    where
188        E: de::Error,
189    {
190        Ok(Value::from(Number::from(v)))
191    }
192
193    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
194    where
195        E: de::Error,
196    {
197        Ok(Value::String(s.to_string().into()))
198    }
199
200    fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
201    where
202        E: de::Error,
203    {
204        Ok(Value::String(s.into()))
205    }
206
207    fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
208    where
209        V: SeqAccess<'de>,
210    {
211        let mut arr = vec![];
212        while let Some(v) = visitor.next_element()? {
213            arr.push(v);
214            // Enforce allocator limit while expanding a deserialized array.
215            enforce_limit_for::<V::Error>()?;
216        }
217        Ok(Value::from(arr))
218    }
219
220    fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
221    where
222        V: MapAccess<'de>,
223    {
224        if let Some((key, value)) = visitor.next_entry()? {
225            if let (Value::String(k), Value::String(v)) = (&key, &value) {
226                if k.as_ref() == "$serde_json::private::Number" {
227                    match Number::from_str(v) {
228                        Ok(n) => return Ok(Value::from(n)),
229                        _ => return Err(de::Error::custom("failed to read big number")),
230                    }
231                }
232            }
233            let mut map = BTreeMap::new();
234            map.insert(key, value);
235            // Enforce allocator limit while expanding a deserialized object.
236            enforce_limit_for::<V::Error>()?;
237            while let Some((key, value)) = visitor.next_entry()? {
238                map.insert(key, value);
239                // Enforce allocator limit while expanding a deserialized object.
240                enforce_limit_for::<V::Error>()?;
241            }
242            Ok(Value::from(map))
243        } else {
244            Ok(Value::new_object())
245        }
246    }
247}
248
249#[doc(hidden)]
250impl<'de> Deserialize<'de> for Value {
251    fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
252    where
253        D: Deserializer<'de>,
254    {
255        deserializer.deserialize_any(ValueVisitor)
256    }
257}
258
259impl fmt::Display for Value {
260    /// Display a value.
261    ///
262    /// A value is displayed by serializing it to JSON using serde_json::to_string.
263    ///
264    /// ```
265    /// # use regorus::*;
266    /// # fn main() -> anyhow::Result<()> {
267    /// let v = Value::from("hello");
268    /// assert_eq!(format!("{v}"), "\"hello\"");
269    /// # Ok(())
270    /// # }
271    /// ```
272    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
273        match serde_json::to_string(self) {
274            Ok(s) => write!(f, "{s}"),
275            Err(_e) => Err(fmt::Error),
276        }
277    }
278}
279
280impl Value {
281    /// Create an empty [`Value::Array`]
282    ///
283    /// ```
284    /// # use regorus::*;
285    /// # fn main() -> anyhow::Result<()> {
286    /// let obj = Value::new_array();
287    /// assert_eq!(obj.as_array().expect("not an array").len(), 0);
288    /// # Ok(())
289    /// # }
290    /// ```
291    pub fn new_array() -> Value {
292        Value::from(vec![])
293    }
294
295    /// Create an empty [`Value::Object`]
296    ///
297    /// ```
298    /// # use regorus::*;
299    /// # fn main() -> anyhow::Result<()> {
300    /// let obj = Value::new_object();
301    /// assert_eq!(obj.as_object().expect("not an object").len(), 0);
302    /// # Ok(())
303    /// # }
304    /// ```
305    pub fn new_object() -> Value {
306        Value::from(BTreeMap::new())
307    }
308
309    /// Create an empty [`Value::Set`]
310    ///
311    /// ```
312    /// # use regorus::*;
313    /// # fn main() -> anyhow::Result<()> {
314    /// let obj = Value::new_set();
315    /// assert_eq!(obj.as_set().expect("not a set").len(), 0);
316    /// # Ok(())
317    /// # }
318    /// ```
319    pub fn new_set() -> Value {
320        Value::from(BTreeSet::new())
321    }
322}
323
324impl Value {
325    /// Deserialize a [`Value`] from JSON.
326    /// ```
327    /// # use regorus::*;
328    /// # fn main() -> anyhow::Result<()> {
329    /// let json = r#"
330    /// [
331    ///   null, true, false,
332    ///   "hello", 12345,
333    ///   { "name" : "regorus" }
334    /// ]"#;
335    ///
336    /// // Deserialize json.
337    /// let value = Value::from_json_str(json)?;
338    ///
339    /// // Assert outer array.
340    /// let array = value.as_array().expect("not an array");
341    ///
342    /// // Assert elements.
343    /// assert_eq!(array[0], Value::Null);
344    /// assert_eq!(array[1], Value::from(true));
345    /// assert_eq!(array[2], Value::from(false));
346    /// assert_eq!(array[3], Value::from("hello"));
347    /// assert_eq!(array[4], Value::from(12345u64));
348    /// let obj = array[5].as_object().expect("not an object");
349    /// assert_eq!(obj.len(), 1);
350    /// assert_eq!(obj[&Value::from("name")], Value::from("regorus"));
351    /// # Ok(())
352    /// # }
353    /// ```
354    pub fn from_json_str(json: &str) -> Result<Value> {
355        match serde_json::from_str::<Value>(json) {
356            Ok(value) => Ok(value),
357            Err(err) => {
358                #[cfg(feature = "allocator-memory-limits")]
359                {
360                    // Re-validate allocator limits when serde parsing fails to surface LimitError.
361                    match crate::utils::limits::check_global_memory_limit() {
362                        Err(limit_err) => Err(anyhow!(limit_err)),
363                        Ok(_) => Err(anyhow!(err)),
364                    }
365                }
366
367                #[cfg(not(feature = "allocator-memory-limits"))]
368                {
369                    Err(anyhow!(err))
370                }
371            }
372        }
373    }
374
375    /// Deserialize a [`Value`] from a file containing JSON.
376    ///
377    /// ```
378    /// # use regorus::*;
379    /// # fn main() -> anyhow::Result<()> {
380    /// let value = Value::from_json_file("tests/aci/input.json")?;
381    ///
382    /// // Convert the value back to json.
383    /// let json_str = value.to_json_str()?;
384    ///
385    /// assert_eq!(
386    ///     json_str.trim(),
387    ///     std::fs::read_to_string("tests/aci/input.json")?
388    ///         .trim()
389    ///         .replace("\r\n", "\n")
390    /// );
391    /// # Ok(())
392    /// # }
393    /// ```
394    #[cfg(feature = "std")]
395    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
396    pub fn from_json_file<P: AsRef<std::path::Path>>(path: P) -> Result<Value> {
397        match std::fs::read_to_string(&path) {
398            Ok(c) => Self::from_json_str(c.as_str()),
399            Err(e) => bail!("Failed to read {}. {e}", path.as_ref().display()),
400        }
401    }
402
403    /// Serialize a value to JSON.
404    ///
405    /// ```
406    /// # use regorus::*;
407    /// # fn main() -> anyhow::Result<()> {
408    /// let value = Value::from_json_file("tests/aci/input.json")?;
409    ///
410    /// // Convert the value back to json.
411    /// let json_str = value.to_json_str()?;
412    ///
413    /// assert_eq!(
414    ///     json_str.trim(),
415    ///     std::fs::read_to_string("tests/aci/input.json")?
416    ///         .trim()
417    ///         .replace("\r\n", "\n")
418    /// );
419    /// # Ok(())
420    /// # }
421    /// ```
422    ///
423    /// Sets are serialized as arrays.
424    /// ```
425    /// # use regorus::*;
426    /// # use std::collections::BTreeSet;
427    /// # fn main() -> anyhow::Result<()> {
428    /// let mut set = BTreeSet::new();
429    /// set.insert(Value::from("Hello"));
430    /// set.insert(Value::from(1u64));
431    ///
432    /// let set_value = Value::from(set);
433    ///
434    /// assert_eq!(
435    ///     set_value.to_json_str()?,
436    ///     r#"
437    /// [
438    ///   1,
439    ///   "Hello"
440    /// ]"#
441    ///     .trim()
442    /// );
443    /// # Ok(())
444    /// # }
445    /// ```
446    ///
447    /// Non string keys of objects are serialized to json first and the serialized string representation
448    /// is emitted as the key.
449    /// ```
450    /// # use regorus::*;
451    /// # use std::collections::BTreeMap;
452    /// # fn main() -> anyhow::Result<()> {
453    /// let mut obj = BTreeMap::new();
454    /// obj.insert(Value::from("Hello"), Value::from("World"));
455    /// obj.insert(Value::from([Value::from(1u64)].to_vec()), Value::Null);
456    ///
457    /// let obj_value = Value::from(obj);
458    ///
459    /// assert_eq!(
460    ///     obj_value.to_json_str()?,
461    ///     r#"
462    /// {
463    ///   "Hello": "World",
464    ///   "[1]": null
465    /// }"#
466    ///     .trim()
467    /// );
468    /// # Ok(())
469    /// # }
470    /// ```
471    pub fn to_json_str(&self) -> Result<String> {
472        serde_json::to_string_pretty(self).map_err(anyhow::Error::msg)
473    }
474
475    /// Deserialize a value from YAML.
476    /// Note: Deserialization from YAML does not support arbitrary precision numbers.
477    #[cfg(feature = "yaml")]
478    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
479    pub fn from_yaml_str(yaml: &str) -> Result<Value> {
480        let value = serde_yaml::from_str(yaml)
481            .map_err(|err| anyhow::anyhow!("Failed to parse YAML: {}", err))?;
482        Ok(value)
483    }
484
485    /// Deserialize a value from a file containing YAML.
486    /// Note: Deserialization from YAML does not support arbitrary precision numbers.
487    #[cfg(feature = "std")]
488    #[cfg(feature = "yaml")]
489    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
490    #[cfg_attr(docsrs, doc(cfg(feature = "yaml")))]
491    pub fn from_yaml_file(path: &String) -> Result<Value> {
492        match std::fs::read_to_string(path) {
493            Ok(c) => Self::from_yaml_str(c.as_str()),
494            Err(e) => bail!("Failed to read {path}. {e}"),
495        }
496    }
497}
498
499impl From<bool> for Value {
500    /// Create a [`Value::Bool`] from `bool`.
501    /// ```
502    /// # use regorus::*;
503    /// # use std::collections::BTreeSet;
504    /// # fn main() -> anyhow::Result<()> {
505    /// assert_eq!(Value::from(true), Value::Bool(true));
506    /// # Ok(())
507    /// # }
508    fn from(b: bool) -> Self {
509        Value::Bool(b)
510    }
511}
512
513impl From<String> for Value {
514    /// Create a [`Value::String`] from `string`.
515    /// ```
516    /// # use regorus::*;
517    /// # fn main() -> anyhow::Result<()> {
518    /// assert_eq!(Value::from("Hello".to_string()), Value::String("Hello".into()));
519    /// # Ok(())
520    /// # }
521    fn from(s: String) -> Self {
522        Value::String(s.into())
523    }
524}
525
526impl From<&str> for Value {
527    /// Create a [`Value::String`] from `&str`.
528    /// ```
529    /// # use regorus::*;
530    /// # fn main() -> anyhow::Result<()> {
531    /// assert_eq!(Value::from("Hello"), Value::String("Hello".into()));
532    /// # Ok(())
533    /// # }
534    fn from(s: &str) -> Self {
535        Value::String(s.into())
536    }
537}
538
539impl From<u128> for Value {
540    /// Create a [`Value::Number`] from `u128`.
541    /// ```
542    /// # use regorus::*;
543    /// # fn main() -> anyhow::Result<()> {
544    /// assert_eq!(
545    ///   Value::from(340_282_366_920_938_463_463_374_607_431_768_211_455u128).as_u128()?,
546    ///   340_282_366_920_938_463_463_374_607_431_768_211_455u128);
547    /// # Ok(())
548    /// # }
549    fn from(n: u128) -> Self {
550        Value::Number(Number::from(n))
551    }
552}
553
554impl From<i128> for Value {
555    /// Create a [`Value::Number`] from `i128`.
556    /// ```
557    /// # use regorus::*;
558    /// # fn main() -> anyhow::Result<()> {
559    /// assert_eq!(
560    ///   Value::from(-170141183460469231731687303715884105728i128).as_i128()?,
561    ///   -170141183460469231731687303715884105728i128);
562    /// # Ok(())
563    /// # }
564    fn from(n: i128) -> Self {
565        Value::Number(Number::from(n))
566    }
567}
568
569impl From<u64> for Value {
570    /// Create a [`Value::Number`] from `u64`.
571    /// ```
572    /// # use regorus::*;
573    /// # fn main() -> anyhow::Result<()> {
574    /// assert_eq!(
575    ///   Value::from(0u64),
576    ///   Value::from_json_str("0")?);
577    /// # Ok(())
578    /// # }
579    fn from(n: u64) -> Self {
580        Value::Number(Number::from(n))
581    }
582}
583
584impl From<i64> for Value {
585    /// Create a [`Value::Number`] from `i64`.
586    /// ```
587    /// # use regorus::*;
588    /// # fn main() -> anyhow::Result<()> {
589    /// assert_eq!(
590    ///   Value::from(0i64),
591    ///   Value::from_json_str("0")?);
592    /// # Ok(())
593    /// # }
594    fn from(n: i64) -> Self {
595        Value::Number(Number::from(n))
596    }
597}
598
599impl From<u32> for Value {
600    /// Create a [`Value::Number`] from `u32`.
601    /// ```
602    /// # use regorus::*;
603    /// # fn main() -> anyhow::Result<()> {
604    /// assert_eq!(
605    ///   Value::from(0u32),
606    ///   Value::from_json_str("0")?);
607    /// # Ok(())
608    /// # }
609    fn from(n: u32) -> Self {
610        Value::Number(Number::from(n as u64))
611    }
612}
613
614impl From<i32> for Value {
615    /// Create a [`Value::Number`] from `i32`.
616    /// ```
617    /// # use regorus::*;
618    /// # fn main() -> anyhow::Result<()> {
619    /// assert_eq!(
620    ///   Value::from(0i32),
621    ///   Value::from_json_str("0")?);
622    /// # Ok(())
623    /// # }
624    fn from(n: i32) -> Self {
625        Value::Number(Number::from(n as i64))
626    }
627}
628
629impl From<f64> for Value {
630    /// Create a [`Value::Number`] from `f64`.
631    /// ```
632    /// # use regorus::*;
633    /// # fn main() -> anyhow::Result<()> {
634    /// assert_eq!(Value::from(3.5f64), Value::from_numeric_string("3.5")?);
635    /// # Ok(())
636    /// # }
637    /// ```
638    ///
639    /// [`Value::Number`] stores floating-point values as `f64`, so it inherits the same
640    /// ~15-digit precision limit. Adding additional digits to either the literal or a parsed
641    /// numeric string causes both to round to the same `f64` value.
642    /// ```
643    /// # use regorus::*;
644    /// # fn main() -> anyhow::Result<()> {
645    /// let from_float = Value::from(3.141592653589793238462f64);
646    /// let from_string = Value::from_numeric_string("3.141592653589793238462")?;
647    /// assert_eq!(from_float, from_string);
648    ///
649    /// // All representations round to approximately 15 digits.
650    /// assert_eq!(from_float, Value::from_numeric_string("3.141592653589793")?);
651    /// # Ok(())
652    /// # }
653    /// ```
654    ///
655    /// If additional precision is required, keep the raw data as strings or use an external
656    /// arbitrary-precision numeric type before converting it into [`Value`].
657    fn from(n: f64) -> Self {
658        Value::Number(Number::from(n))
659    }
660}
661
662impl From<serde_json::Value> for Value {
663    /// Create a [`Value`] from [`serde_json::Value`].
664    ///
665    /// Returns [`Value::Undefined`] in case of error.
666    /// ```
667    /// # use regorus::*;
668    /// # fn main() -> anyhow::Result<()> {
669    /// let json_v = serde_json::json!({ "x":10, "y": 20 });
670    /// let v = Value::from(json_v);
671    ///
672    /// assert_eq!(v["x"].as_u64()?, 10);
673    /// assert_eq!(v["y"].as_u64()?, 20);
674    /// # Ok(())
675    /// # }
676    fn from(v: serde_json::Value) -> Self {
677        match serde_json::from_value(v) {
678            Ok(v) => v,
679            _ => Value::Undefined,
680        }
681    }
682}
683
684#[cfg(feature = "yaml")]
685#[cfg_attr(docsrs, doc(cfg(feature = "yaml")))]
686impl From<serde_yaml::Value> for Value {
687    /// Create a [`Value`] from [`serde_yaml::Value`].
688    ///
689    /// Returns [`Value::Undefined`] in case of error.
690    /// ```
691    /// # use regorus::*;
692    /// # fn main() -> anyhow::Result<()> {
693    /// let yaml = "
694    ///   x: 10
695    ///   y: 20
696    /// ";
697    /// let yaml_v : serde_yaml::Value = serde_yaml::from_str(&yaml).unwrap();
698    /// let v = Value::from(yaml_v);
699    ///
700    /// assert_eq!(v["x"].as_u64()?, 10);
701    /// assert_eq!(v["y"].as_u64()?, 20);
702    /// # Ok(())
703    /// # }
704    fn from(v: serde_yaml::Value) -> Self {
705        match serde_yaml::from_value(v) {
706            Ok(v) => v,
707            _ => Value::Undefined,
708        }
709    }
710}
711
712impl Value {
713    /// Create a [`Value::Number`] from a string containing numeric representation of a number.
714    ///
715    /// This is the preferred way for creating arbitrary precision numbers.
716    ///
717    /// ```
718    /// # use regorus::*;
719    /// # fn main() -> anyhow::Result<()> {
720    /// let v = Value::from_numeric_string("3.14159265358979323846264338327950288419716939937510")?;
721    ///
722    /// println!("{}", v.to_json_str()?);
723    /// // Prints 3.1415926535897932384626433832795028841971693993751 if serde_json/arbitrary_precision feature is enabled.
724    /// // Prints 3.141592653589793 if serde_json/arbitrary_precision is not enabled.
725    /// # Ok(())
726    /// # }
727    /// ```
728    pub fn from_numeric_string(s: &str) -> Result<Value> {
729        Ok(Value::Number(
730            Number::from_str(s).map_err(|_| anyhow!("not a valid numeric string"))?,
731        ))
732    }
733}
734
735impl From<usize> for Value {
736    /// Create a [`Value::Number`] from `usize`.
737    /// ```
738    /// # use regorus::*;
739    /// # fn main() -> anyhow::Result<()> {
740    /// assert_eq!(
741    ///   Value::from(0usize),
742    ///   Value::from_json_str("0")?);
743    /// # Ok(())
744    /// # }
745    fn from(n: usize) -> Self {
746        Value::Number(Number::from(n))
747    }
748}
749
750#[doc(hidden)]
751impl From<Number> for Value {
752    fn from(n: Number) -> Self {
753        Value::Number(n)
754    }
755}
756
757impl From<Vec<Value>> for Value {
758    /// Create a [`Value::Array`] from a [`Vec<Value>`].
759    /// ```
760    /// # use regorus::*;
761    /// # fn main() -> anyhow::Result<()> {
762    /// let strings = [ "Hello", "World" ];
763    ///
764    /// let v = Value::from(strings.iter().map(|s| Value::from(*s)).collect::<Vec<Value>>());
765    /// assert_eq!(v[0], Value::from(strings[0]));
766    /// assert_eq!(v[1], Value::from(strings[1]));
767    /// # Ok(())
768    /// # }
769    fn from(a: Vec<Value>) -> Self {
770        Value::Array(Rc::new(a))
771    }
772}
773
774impl From<BTreeSet<Value>> for Value {
775    /// Create a [`Value::Set`] from a [`BTreeSet<Value>`].
776    /// ```
777    /// # use regorus::*;
778    /// # use std::collections::BTreeSet;
779    /// # fn main() -> anyhow::Result<()> {
780    /// let strings = [ "Hello", "World" ];
781    /// let v = Value::from(strings
782    ///            .iter()
783    ///            .map(|s| Value::from(*s))
784    ///            .collect::<BTreeSet<Value>>());
785    ///
786    /// let mut iter = v.as_set()?.iter();
787    /// assert_eq!(iter.next(), Some(&Value::from(strings[0])));
788    /// assert_eq!(iter.next(), Some(&Value::from(strings[1])));
789    /// # Ok(())
790    /// # }
791    fn from(s: BTreeSet<Value>) -> Self {
792        Value::Set(Rc::new(s))
793    }
794}
795
796impl From<BTreeMap<Value, Value>> for Value {
797    /// Create a [`Value::Object`] from a [`BTreeMap<Value>`].
798    /// ```
799    /// # use regorus::*;
800    /// # use std::collections::BTreeMap;
801    /// # fn main() -> anyhow::Result<()> {
802    /// let strings = [ ("Hello", "World") ];
803    /// let v = Value::from(strings
804    ///            .iter()
805    ///            .map(|(k,v)| (Value::from(*k), Value::from(*v)))
806    ///            .collect::<BTreeMap<Value, Value>>());
807    ///
808    /// let mut iter = v.as_object()?.iter();
809    /// assert_eq!(iter.next(), Some((&Value::from(strings[0].0), &Value::from(strings[0].1))));
810    /// # Ok(())
811    /// # }
812    fn from(s: BTreeMap<Value, Value>) -> Self {
813        Value::Object(Rc::new(s))
814    }
815}
816
817impl Value {
818    pub(crate) fn from_array(a: Vec<Value>) -> Value {
819        Value::from(a)
820    }
821
822    pub(crate) fn from_set(s: BTreeSet<Value>) -> Value {
823        Value::from(s)
824    }
825
826    pub(crate) fn from_map(m: BTreeMap<Value, Value>) -> Value {
827        Value::from(m)
828    }
829
830    pub(crate) fn is_empty_object(&self) -> bool {
831        self == &Value::new_object()
832    }
833}
834
835impl Value {
836    /// Cast value to [`& bool`] if [`Value::Bool`].
837    /// ```
838    /// # use regorus::*;
839    /// # fn main() -> anyhow::Result<()> {
840    /// let v = Value::from(true);
841    /// assert_eq!(v.as_bool()?, &true);
842    /// # Ok(())
843    /// # }
844    pub fn as_bool(&self) -> Result<&bool> {
845        match self {
846            Value::Bool(b) => Ok(b),
847            _ => Err(anyhow!("not a bool")),
848        }
849    }
850
851    /// Cast value to [`&mut bool`] if [`Value::Bool`].
852    /// ```
853    /// # use regorus::*;
854    /// # fn main() -> anyhow::Result<()> {
855    /// let mut v = Value::from(true);
856    /// *v.as_bool_mut()? = false;
857    /// # Ok(())
858    /// # }
859    pub fn as_bool_mut(&mut self) -> Result<&mut bool> {
860        match self {
861            Value::Bool(b) => Ok(b),
862            _ => Err(anyhow!("not a bool")),
863        }
864    }
865
866    /// Cast value to [`& u128`] if [`Value::Number`].
867    ///
868    /// Error is raised if the value is not a number or if the numeric value
869    /// does not fit in a u128.
870    ///
871    /// ```
872    /// # use regorus::*;
873    /// # fn main() -> anyhow::Result<()> {
874    /// let v = Value::from(10);
875    /// assert_eq!(v.as_u128()?, 10u128);
876    ///
877    /// let v = Value::from(-10);
878    /// assert!(v.as_u128().is_err());
879    /// # Ok(())
880    /// # }
881    pub fn as_u128(&self) -> Result<u128> {
882        match self {
883            Value::Number(b) => {
884                if let Some(n) = b.as_u128() {
885                    return Ok(n);
886                }
887                bail!("not a u128");
888            }
889            _ => Err(anyhow!("not a u128")),
890        }
891    }
892
893    /// Cast value to [`& i128`] if [`Value::Number`].
894    ///
895    /// Error is raised if the value is not a number or if the numeric value
896    /// does not fit in a i128.
897    ///
898    /// ```
899    /// # use regorus::*;
900    /// # fn main() -> anyhow::Result<()> {
901    /// let v = Value::from(-10);
902    /// assert_eq!(v.as_i128()?, -10i128);
903    ///
904    /// let v = Value::from_numeric_string("11111111111111111111111111111111111111111111111111")?;
905    /// assert!(v.as_i128().is_err());
906    /// # Ok(())
907    /// # }
908    pub fn as_i128(&self) -> Result<i128> {
909        match self {
910            Value::Number(b) => {
911                if let Some(n) = b.as_i128() {
912                    return Ok(n);
913                }
914                bail!("not a i128");
915            }
916            _ => Err(anyhow!("not a i128")),
917        }
918    }
919
920    /// Cast value to [`& u64`] if [`Value::Number`].
921    ///
922    /// Error is raised if the value is not a number or if the numeric value
923    /// does not fit in a u64.
924    ///
925    /// ```
926    /// # use regorus::*;
927    /// # fn main() -> anyhow::Result<()> {
928    /// let v = Value::from(10);
929    /// assert_eq!(v.as_u64()?, 10u64);
930    ///
931    /// let v = Value::from(-10);
932    /// assert!(v.as_u64().is_err());
933    /// # Ok(())
934    /// # }
935    pub fn as_u64(&self) -> Result<u64> {
936        match self {
937            Value::Number(b) => {
938                if let Some(n) = b.as_u64() {
939                    return Ok(n);
940                }
941                bail!("not a u64");
942            }
943            _ => Err(anyhow!("not a u64")),
944        }
945    }
946
947    /// Cast value to [`& i64`] if [`Value::Number`].
948    ///
949    /// Error is raised if the value is not a number or if the numeric value
950    /// does not fit in a i64.
951    ///
952    /// ```
953    /// # use regorus::*;
954    /// # fn main() -> anyhow::Result<()> {
955    /// let v = Value::from(-10);
956    /// assert_eq!(v.as_i64()?, -10i64);
957    ///
958    /// let v = Value::from(340_282_366_920_938_463_463_374_607_431_768_211_455u128);
959    /// assert!(v.as_i64().is_err());
960    /// # Ok(())
961    /// # }
962    pub fn as_i64(&self) -> Result<i64> {
963        match self {
964            Value::Number(b) => {
965                if let Some(n) = b.as_i64() {
966                    return Ok(n);
967                }
968                bail!("not an i64");
969            }
970            _ => Err(anyhow!("not an i64")),
971        }
972    }
973
974    /// Cast value to [`& u32`] if [`Value::Number`].
975    ///
976    /// Error is raised if the value is not a number or if the numeric value
977    /// does not fit in a u32.
978    ///
979    /// ```
980    /// # use regorus::*;
981    /// # fn main() -> anyhow::Result<()> {
982    /// let v = Value::from(10);
983    /// assert_eq!(v.as_u32()?, 10u32);
984    ///
985    /// let v = Value::from(-10);
986    /// assert!(v.as_u32().is_err());
987    /// # Ok(())
988    /// # }
989    pub fn as_u32(&self) -> Result<u32> {
990        match self {
991            Value::Number(b) => {
992                if let Some(n) = b.as_u64() {
993                    if let Ok(v) = u32::try_from(n) {
994                        return Ok(v);
995                    }
996                }
997                bail!("not a u32");
998            }
999            _ => Err(anyhow!("not a u32")),
1000        }
1001    }
1002
1003    /// Cast value to [`& i32`] if [`Value::Number`].
1004    ///
1005    /// Error is raised if the value is not a number or if the numeric value
1006    /// does not fit in a i32.
1007    ///
1008    /// ```
1009    /// # use regorus::*;
1010    /// # fn main() -> anyhow::Result<()> {
1011    /// let v = Value::from(-10);
1012    /// assert_eq!(v.as_i32()?, -10i32);
1013    ///
1014    /// let v = Value::from(2_147_483_648i64);
1015    /// assert!(v.as_i32().is_err());
1016    /// # Ok(())
1017    /// # }
1018    pub fn as_i32(&self) -> Result<i32> {
1019        match self {
1020            Value::Number(b) => {
1021                if let Some(n) = b.as_i64() {
1022                    if let Ok(v) = i32::try_from(n) {
1023                        return Ok(v);
1024                    }
1025                }
1026                bail!("not an i32");
1027            }
1028            _ => Err(anyhow!("not an i32")),
1029        }
1030    }
1031
1032    /// Cast value to [`& u16`] if [`Value::Number`].
1033    ///
1034    /// Error is raised if the value is not a number or if the numeric value
1035    /// does not fit in a u16.
1036    ///
1037    /// ```
1038    /// # use regorus::*;
1039    /// # fn main() -> anyhow::Result<()> {
1040    /// let v = Value::from(10);
1041    /// assert_eq!(v.as_u16()?, 10u16);
1042    ///
1043    /// let v = Value::from(-10);
1044    /// assert!(v.as_u16().is_err());
1045    /// # Ok(())
1046    /// # }
1047    pub fn as_u16(&self) -> Result<u16> {
1048        match self {
1049            Value::Number(b) => {
1050                if let Some(n) = b.as_u64() {
1051                    if let Ok(v) = u16::try_from(n) {
1052                        return Ok(v);
1053                    }
1054                }
1055                bail!("not a u16");
1056            }
1057            _ => Err(anyhow!("not a u16")),
1058        }
1059    }
1060
1061    /// Cast value to [`& i16`] if [`Value::Number`].
1062    ///
1063    /// Error is raised if the value is not a number or if the numeric value
1064    /// does not fit in a i16.
1065    ///
1066    /// ```
1067    /// # use regorus::*;
1068    /// # fn main() -> anyhow::Result<()> {
1069    /// let v = Value::from(-10);
1070    /// assert_eq!(v.as_i16()?, -10i16);
1071    ///
1072    /// let v = Value::from(32768i64);
1073    /// assert!(v.as_i16().is_err());
1074    /// # Ok(())
1075    /// # }
1076    pub fn as_i16(&self) -> Result<i16> {
1077        match self {
1078            Value::Number(b) => {
1079                if let Some(n) = b.as_i64() {
1080                    if let Ok(v) = i16::try_from(n) {
1081                        return Ok(v);
1082                    }
1083                }
1084                bail!("not an i16");
1085            }
1086            _ => Err(anyhow!("not an i16")),
1087        }
1088    }
1089
1090    /// Cast value to [`& u8`] if [`Value::Number`].
1091    ///
1092    /// Error is raised if the value is not a number or if the numeric value
1093    /// does not fit in a u8.
1094    ///
1095    /// ```
1096    /// # use regorus::*;
1097    /// # fn main() -> anyhow::Result<()> {
1098    /// let v = Value::from(10);
1099    /// assert_eq!(v.as_u8()?, 10u8);
1100    ///
1101    /// let v = Value::from(-10);
1102    /// assert!(v.as_u8().is_err());
1103    /// # Ok(())
1104    /// # }
1105    pub fn as_u8(&self) -> Result<u8> {
1106        match self {
1107            Value::Number(b) => {
1108                if let Some(n) = b.as_u64() {
1109                    if let Ok(v) = u8::try_from(n) {
1110                        return Ok(v);
1111                    }
1112                }
1113                bail!("not a u8");
1114            }
1115            _ => Err(anyhow!("not a u8")),
1116        }
1117    }
1118
1119    /// Cast value to [`& i8`] if [`Value::Number`].
1120    ///
1121    /// Error is raised if the value is not a number or if the numeric value
1122    /// does not fit in a i8.
1123    ///
1124    /// ```
1125    /// # use regorus::*;
1126    /// # fn main() -> anyhow::Result<()> {
1127    /// let v = Value::from(-10);
1128    /// assert_eq!(v.as_i8()?, -10i8);
1129    ///
1130    /// let v = Value::from(128);
1131    /// assert!(v.as_i8().is_err());
1132    /// # Ok(())
1133    /// # }
1134    pub fn as_i8(&self) -> Result<i8> {
1135        match self {
1136            Value::Number(b) => {
1137                if let Some(n) = b.as_i64() {
1138                    if let Ok(v) = i8::try_from(n) {
1139                        return Ok(v);
1140                    }
1141                }
1142                bail!("not an i8");
1143            }
1144            _ => Err(anyhow!("not an i8")),
1145        }
1146    }
1147
1148    /// Cast value to [`& f64`] if [`Value::Number`].
1149    /// Error is raised if the value is not a number or if the numeric value
1150    /// does not fit in a i64.
1151    ///
1152    /// ```
1153    /// # use regorus::*;
1154    /// # fn main() -> anyhow::Result<()> {
1155    /// let v = Value::from(-10);
1156    /// assert_eq!(v.as_f64()?, -10f64);
1157    ///
1158    /// let v = Value::from(340_282_366_920_938_463_463_374_607_431_768_211_455u128);
1159    /// assert!(v.as_i64().is_err());
1160    /// # Ok(())
1161    /// # }
1162    pub fn as_f64(&self) -> Result<f64> {
1163        match self {
1164            Value::Number(b) => {
1165                if let Some(n) = b.as_f64() {
1166                    return Ok(n);
1167                }
1168                bail!("not a f64");
1169            }
1170            _ => Err(anyhow!("not a f64")),
1171        }
1172    }
1173
1174    /// Cast value to [`& Rc<str>`] if [`Value::String`].
1175    /// ```
1176    /// # use regorus::*;
1177    /// # fn main() -> anyhow::Result<()> {
1178    /// let v = Value::from("Hello");
1179    /// assert_eq!(v.as_string()?.as_ref(), "Hello");
1180    /// # Ok(())
1181    /// # }
1182    pub fn as_string(&self) -> Result<&Rc<str>> {
1183        match self {
1184            Value::String(s) => Ok(s),
1185            _ => Err(anyhow!("not a string")),
1186        }
1187    }
1188
1189    /// Cast value to [`&mut Rc<str>`] if [`Value::String`].
1190    /// ```
1191    /// # use regorus::*;
1192    /// # fn main() -> anyhow::Result<()> {
1193    /// let mut v = Value::from("Hello");
1194    /// *v.as_string_mut()? = "World".into();
1195    /// # Ok(())
1196    /// # }
1197    pub fn as_string_mut(&mut self) -> Result<&mut Rc<str>> {
1198        match self {
1199            Value::String(s) => Ok(s),
1200            _ => Err(anyhow!("not a string")),
1201        }
1202    }
1203
1204    #[doc(hidden)]
1205    pub fn as_number(&self) -> Result<&Number> {
1206        match self {
1207            Value::Number(n) => Ok(n),
1208            _ => Err(anyhow!("not a number")),
1209        }
1210    }
1211
1212    #[doc(hidden)]
1213    pub fn as_number_mut(&mut self) -> Result<&mut Number> {
1214        match self {
1215            Value::Number(n) => Ok(n),
1216            _ => Err(anyhow!("not a number")),
1217        }
1218    }
1219
1220    /// Cast value to [`& Vec<Value>`] if [`Value::Array`].
1221    /// ```
1222    /// # use regorus::*;
1223    /// # fn main() -> anyhow::Result<()> {
1224    /// let v = Value::from([Value::from("Hello")].to_vec());
1225    /// assert_eq!(v.as_array()?[0], Value::from("Hello"));
1226    /// # Ok(())
1227    /// # }
1228    pub fn as_array(&self) -> Result<&Vec<Value>> {
1229        match self {
1230            Value::Array(a) => Ok(a),
1231            _ => Err(anyhow!("not an array")),
1232        }
1233    }
1234
1235    /// Cast value to [`&mut Vec<Value>`] if [`Value::Array`].
1236    /// ```
1237    /// # use regorus::*;
1238    /// # fn main() -> anyhow::Result<()> {
1239    /// let mut v = Value::from([Value::from("Hello")].to_vec());
1240    /// v.as_array_mut()?.push(Value::from("World"));
1241    /// # Ok(())
1242    /// # }
1243    pub fn as_array_mut(&mut self) -> Result<&mut Vec<Value>> {
1244        match self {
1245            Value::Array(a) => Ok(Rc::make_mut(a)),
1246            _ => Err(anyhow!("not an array")),
1247        }
1248    }
1249
1250    /// Cast value to [`& BTreeSet<Value>`] if [`Value::Set`].
1251    /// ```
1252    /// # use regorus::*;
1253    /// # use std::collections::BTreeSet;
1254    /// # fn main() -> anyhow::Result<()> {
1255    /// let v = Value::from(
1256    ///    [Value::from("Hello")]
1257    ///        .iter()
1258    ///        .cloned()
1259    ///        .collect::<BTreeSet<Value>>(),
1260    /// );
1261    /// assert_eq!(v.as_set()?.first(), Some(&Value::from("Hello")));
1262    /// # Ok(())
1263    /// # }
1264    pub fn as_set(&self) -> Result<&BTreeSet<Value>> {
1265        match self {
1266            Value::Set(s) => Ok(s),
1267            _ => Err(anyhow!("not a set")),
1268        }
1269    }
1270
1271    /// Cast value to [`&mut BTreeSet<Value>`] if [`Value::Set`].
1272    /// ```
1273    /// # use regorus::*;
1274    /// # use std::collections::BTreeSet;
1275    /// # fn main() -> anyhow::Result<()> {
1276    /// let mut v = Value::from(
1277    ///    [Value::from("Hello")]
1278    ///        .iter()
1279    ///        .cloned()
1280    ///        .collect::<BTreeSet<Value>>(),
1281    /// );
1282    /// v.as_set_mut()?.insert(Value::from("World"));
1283    /// # Ok(())
1284    /// # }
1285    pub fn as_set_mut(&mut self) -> Result<&mut BTreeSet<Value>> {
1286        match self {
1287            Value::Set(s) => Ok(Rc::make_mut(s)),
1288            _ => Err(anyhow!("not a set")),
1289        }
1290    }
1291
1292    /// Cast value to [`& BTreeMap<Value, Value>`] if [`Value::Object`].
1293    /// ```
1294    /// # use regorus::*;
1295    /// # use std::collections::BTreeMap;
1296    /// # fn main() -> anyhow::Result<()> {
1297    /// let v = Value::from(
1298    ///    [(Value::from("Hello"), Value::from("World"))]
1299    ///        .iter()
1300    ///        .cloned()
1301    ///        .collect::<BTreeMap<Value, Value>>(),
1302    /// );
1303    /// assert_eq!(
1304    ///    v.as_object()?.iter().next(),
1305    ///    Some((&Value::from("Hello"), &Value::from("World"))),
1306    /// );
1307    /// # Ok(())
1308    /// # }
1309    pub fn as_object(&self) -> Result<&BTreeMap<Value, Value>> {
1310        match self {
1311            Value::Object(m) => Ok(m),
1312            _ => Err(anyhow!("not an object")),
1313        }
1314    }
1315
1316    /// Cast value to [`&mut BTreeMap<Value, Value>`] if [`Value::Object`].
1317    /// ```
1318    /// # use regorus::*;
1319    /// # use std::collections::BTreeMap;
1320    /// # fn main() -> anyhow::Result<()> {
1321    /// let mut v = Value::from(
1322    ///    [(Value::from("Hello"), Value::from("World"))]
1323    ///        .iter()
1324    ///        .cloned()
1325    ///        .collect::<BTreeMap<Value, Value>>(),
1326    /// );
1327    /// v.as_object_mut()?.insert(Value::from("Good"), Value::from("Bye"));
1328    /// # Ok(())
1329    /// # }
1330    pub fn as_object_mut(&mut self) -> Result<&mut BTreeMap<Value, Value>> {
1331        match self {
1332            Value::Object(m) => Ok(Rc::make_mut(m)),
1333            _ => Err(anyhow!("not an object")),
1334        }
1335    }
1336}
1337
1338impl Value {
1339    pub(crate) fn make_or_get_value_mut<'a>(&'a mut self, paths: &[&str]) -> Result<&'a mut Value> {
1340        if paths.is_empty() {
1341            return Ok(self);
1342        }
1343
1344        let key = Value::String(paths[0].into());
1345        if self == &Value::Undefined {
1346            *self = Value::new_object();
1347        }
1348        if let Value::Object(map) = self {
1349            if map.get(&key).is_none() {
1350                Rc::make_mut(map).insert(key.clone(), Value::Undefined);
1351                // Enforce allocator limit while creating nested object entries.
1352                enforce_limit_anyhow()?;
1353            }
1354        }
1355
1356        match self {
1357            Value::Object(map) => match Rc::make_mut(map).get_mut(&key) {
1358                Some(v) if paths.len() == 1 => Ok(v),
1359                Some(v) => Self::make_or_get_value_mut(v, &paths[1..]),
1360                _ => bail!("internal error: unexpected"),
1361            },
1362            Value::Undefined if paths.len() > 1 => {
1363                *self = Value::new_object();
1364                Self::make_or_get_value_mut(self, paths)
1365            }
1366            Value::Undefined => Ok(self),
1367            _ => bail!("internal error: make: not an selfect {self:?}"),
1368        }
1369    }
1370
1371    pub(crate) fn merge(&mut self, mut new: Value) -> Result<()> {
1372        if self == &new {
1373            return Ok(());
1374        }
1375        match (self, &mut new) {
1376            (v @ Value::Undefined, _) => *v = new,
1377            (Value::Set(ref mut set), Value::Set(new)) => {
1378                Rc::make_mut(set).append(Rc::make_mut(new));
1379                // Enforce allocator limit after merging set entries.
1380                enforce_limit_anyhow()?;
1381            }
1382            (Value::Object(map), Value::Object(new)) => {
1383                for (k, v) in new.iter() {
1384                    match map.get(k) {
1385                        Some(pv) if *pv != *v => {
1386                            bail!(
1387                                "value for key `{}` generated multiple times: `{}` and `{}`",
1388                                serde_json::to_string_pretty(&k).map_err(anyhow::Error::msg)?,
1389                                serde_json::to_string_pretty(&pv).map_err(anyhow::Error::msg)?,
1390                                serde_json::to_string_pretty(&v).map_err(anyhow::Error::msg)?,
1391                            )
1392                        }
1393                        _ => {
1394                            Rc::make_mut(map).insert(k.clone(), v.clone());
1395                            // Enforce allocator limit after merging object entries.
1396                            enforce_limit_anyhow()?;
1397                        }
1398                    };
1399                }
1400            }
1401            _ => bail!("error: could not merge value"),
1402        };
1403        Ok(())
1404    }
1405}
1406
1407impl ops::Index<&Value> for Value {
1408    type Output = Value;
1409
1410    /// Index a [`Value`] using a [`Value`].
1411    ///
1412    /// [`Value::Undefined`] is returned
1413    /// - If the index not valid for the collection.
1414    /// - If the value being indexed is not an array, set or object.
1415    ///
1416    /// Sets can be indexed only by elements within the set.
1417    ///
1418    /// ```
1419    /// # use regorus::*;
1420    /// # use std::collections::BTreeMap;
1421    /// # fn main() -> anyhow::Result<()> {
1422    ///
1423    /// let arr = Value::from([Value::from("Hello")].to_vec());
1424    /// // Index an array.
1425    /// assert_eq!(arr[&Value::from(0)].as_string()?.as_ref(), "Hello");
1426    /// assert_eq!(arr[&Value::from(10)], Value::Undefined);
1427    ///
1428    /// let mut set = Value::new_set();
1429    /// set.as_set_mut()?.insert(Value::from(100));
1430    /// set.as_set_mut()?.insert(Value::from("Hello"));
1431    ///
1432    /// // Index a set.
1433    /// let item = Value::from("Hello");
1434    /// assert_eq!(&set[&item], &item);
1435    /// assert_eq!(&set[&Value::from(10)], &Value::Undefined);
1436    ///
1437    /// let mut obj = Value::new_object();
1438    /// obj.as_object_mut()?
1439    ///     .insert(Value::from("Hello"), Value::from("World"));
1440    /// obj.as_object_mut()?
1441    ///     .insert(Value::new_array(), Value::from("bye"));
1442    ///
1443    /// // Index an object.
1444    /// assert_eq!(&obj[Value::from("Hello")].as_string()?.as_ref(), &"World");
1445    /// assert_eq!(&obj[Value::from("hllo")], &Value::Undefined);
1446    /// // Index using non-string key.
1447    /// assert_eq!(&obj[&Value::new_array()].as_string()?.as_ref(), &"bye");
1448    ///
1449    /// // Index a non-collection.
1450    /// assert_eq!(&Value::Null[&Value::from(1)], &Value::Undefined);
1451    /// # Ok(())
1452    /// # }
1453    /// ```
1454    ///
1455    /// This is the preferred way of indexing a value.
1456    /// Since constructing a value may be a costly operation (e.g. Value::String),
1457    /// the caller can construct the index value once and use it many times.
1458    ///`
1459    fn index(&self, key: &Value) -> &Self::Output {
1460        match (self, key) {
1461            (Value::Object(o), _) => match &o.get(key) {
1462                Some(v) => v,
1463                _ => &Value::Undefined,
1464            },
1465            (Value::Set(s), _) => match s.get(key) {
1466                Some(v) => v,
1467                _ => &Value::Undefined,
1468            },
1469            (Value::Array(a), Value::Number(n)) => match n.as_u64() {
1470                Some(index) if (index as usize) < a.len() => &a[index as usize],
1471                _ => &Value::Undefined,
1472            },
1473            _ => &Value::Undefined,
1474        }
1475    }
1476}
1477
1478impl<T> ops::Index<T> for Value
1479where
1480    Value: From<T>,
1481{
1482    type Output = Value;
1483
1484    /// Index a [`Value`].
1485    ///
1486    ///
1487    /// A [`Value`] is constructed from the index which is then used for indexing.
1488    ///
1489    /// ```
1490    /// # use regorus::*;
1491    /// # use std::collections::BTreeMap;
1492    /// # fn main() -> anyhow::Result<()> {
1493    /// let v = Value::from(
1494    ///    [(Value::from("Hello"), Value::from("World")),
1495    ///     (Value::from(1), Value::from(2))]
1496    ///        .iter()
1497    ///        .cloned()
1498    ///        .collect::<BTreeMap<Value, Value>>(),
1499    /// );
1500    ///
1501    /// assert_eq!(&v["Hello"].as_string()?.as_ref(), &"World");
1502    /// assert_eq!(&v[1].as_u64()?, &2u64);
1503    /// # Ok(())
1504    /// # }
1505    fn index(&self, key: T) -> &Self::Output {
1506        &self[&Value::from(key)]
1507    }
1508}