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