pub enum Value {
Null,
Bool(bool),
Number(Number),
String(Rc<str>),
Array(Rc<Vec<Value>>),
Set(Rc<BTreeSet<Value>>),
Object(Rc<BTreeMap<Value, Value>>),
Undefined,
}
Expand description
A value in a Rego document.
Value is similar to a serde_json::value::Value
, but has the following additional
capabilities:
Value::Set
variant to represent sets.Value::Undefined
variant to represent absence of value.Value::Number
has at least 100 digits of precision for computations.
Value can be efficiently cloned due to the use of reference counting.
Variants§
Null
JSON null.
Bool(bool)
JSON boolean.
Number(Number)
JSON number. At least 100 digits of precision.
String(Rc<str>)
JSON string.
Array(Rc<Vec<Value>>)
JSON array.
Set(Rc<BTreeSet<Value>>)
A set of values. No JSON equivalent. Sets are serialized as arrays in JSON.
Object(Rc<BTreeMap<Value, Value>>)
An object. Unlike JSON, keys can be any value, not just string.
Undefined
Undefined value. Used to indicate the absence of a value.
Implementations§
Source§impl Value
impl Value
Sourcepub fn new_array() -> Value
pub fn new_array() -> Value
Create an empty Value::Array
let obj = Value::new_array();
assert_eq!(obj.as_array().expect("not an array").len(), 0);
Sourcepub fn new_object() -> Value
pub fn new_object() -> Value
Create an empty Value::Object
let obj = Value::new_object();
assert_eq!(obj.as_object().expect("not an object").len(), 0);
Sourcepub fn new_set() -> Value
pub fn new_set() -> Value
Create an empty Value::Set
let obj = Value::new_set();
assert_eq!(obj.as_set().expect("not a set").len(), 0);
Source§impl Value
impl Value
Sourcepub fn from_json_str(json: &str) -> Result<Value>
pub fn from_json_str(json: &str) -> Result<Value>
Deserialize a Value
from JSON.
let json = r#"
[
null, true, false,
"hello", 12345,
{ "name" : "regorus" }
]"#;
// Deserialize json.
let value = Value::from_json_str(json)?;
// Assert outer array.
let array = value.as_array().expect("not an array");
// Assert elements.
assert_eq!(array[0], Value::Null);
assert_eq!(array[1], Value::from(true));
assert_eq!(array[2], Value::from(false));
assert_eq!(array[3], Value::from("hello"));
assert_eq!(array[4], Value::from(12345u64));
let obj = array[5].as_object().expect("not an object");
assert_eq!(obj.len(), 1);
assert_eq!(obj[&Value::from("name")], Value::from("regorus"));
Sourcepub fn to_json_str(&self) -> Result<String>
pub fn to_json_str(&self) -> Result<String>
Serialize a value to JSON.
let value = Value::from_json_file("tests/aci/input.json")?;
// Convert the value back to json.
let json_str = value.to_json_str()?;
assert_eq!(json_str.trim(),
std::fs::read_to_string("tests/aci/input.json")?.trim().replace("\r\n", "\n"));
Sets are serialized as arrays.
let mut set = BTreeSet::new();
set.insert(Value::from("Hello"));
set.insert(Value::from(1u64));
let set_value = Value::from(set);
assert_eq!(
set_value.to_json_str()?,
r#"
[
1,
"Hello"
]"#.trim());
Non string keys of objects are serialized to json first and the serialized string representation is emitted as the key.
let mut obj = BTreeMap::new();
obj.insert(Value::from("Hello"), Value::from("World"));
obj.insert(Value::from([Value::from(1u64)].to_vec()), Value::Null);
let obj_value = Value::from(obj);
assert_eq!(
obj_value.to_json_str()?,
r#"
{
"Hello": "World",
"[1]": null
}"#.trim());
Source§impl Value
impl Value
Sourcepub fn from_numeric_string(s: &str) -> Result<Value>
pub fn from_numeric_string(s: &str) -> Result<Value>
Create a Value::Number
from a string containing numeric representation of a number.
This is the preferred way for creating arbitrary precision numbers.
let v = Value::from_numeric_string("3.14159265358979323846264338327950288419716939937510")?;
println!("{}", v.to_json_str()?);
// Prints 3.1415926535897932384626433832795028841971693993751 if serde_json/arbitrary_precision feature is enabled.
// Prints 3.141592653589793 if serde_json/arbitrary_precision is not enabled.
Source§impl Value
impl Value
Sourcepub fn as_bool(&self) -> Result<&bool>
pub fn as_bool(&self) -> Result<&bool>
Cast value to [& bool
] if Value::Bool
.
let v = Value::from(true);
assert_eq!(v.as_bool()?, &true);
Sourcepub fn as_bool_mut(&mut self) -> Result<&mut bool>
pub fn as_bool_mut(&mut self) -> Result<&mut bool>
Cast value to [&mut bool
] if Value::Bool
.
let mut v = Value::from(true);
*v.as_bool_mut()? = false;
Sourcepub fn as_u128(&self) -> Result<u128>
pub fn as_u128(&self) -> Result<u128>
Cast value to [& u128
] if Value::Number
.
Error is raised if the value is not a number or if the numeric value does not fit in a u128.
let v = Value::from(10);
assert_eq!(v.as_u128()?, 10u128);
let v = Value::from(-10);
assert!(v.as_u128().is_err());
Sourcepub fn as_i128(&self) -> Result<i128>
pub fn as_i128(&self) -> Result<i128>
Cast value to [& i128
] if Value::Number
.
Error is raised if the value is not a number or if the numeric value does not fit in a i128.
let v = Value::from(-10);
assert_eq!(v.as_i128()?, -10i128);
let v = Value::from_numeric_string("11111111111111111111111111111111111111111111111111")?;
assert!(v.as_i128().is_err());
Sourcepub fn as_u64(&self) -> Result<u64>
pub fn as_u64(&self) -> Result<u64>
Cast value to [& u64
] if Value::Number
.
Error is raised if the value is not a number or if the numeric value does not fit in a u64.
let v = Value::from(10);
assert_eq!(v.as_u64()?, 10u64);
let v = Value::from(-10);
assert!(v.as_u64().is_err());
Sourcepub fn as_i64(&self) -> Result<i64>
pub fn as_i64(&self) -> Result<i64>
Cast value to [& i64
] if Value::Number
.
Error is raised if the value is not a number or if the numeric value does not fit in a i64.
let v = Value::from(-10);
assert_eq!(v.as_i64()?, -10i64);
let v = Value::from(340_282_366_920_938_463_463_374_607_431_768_211_455u128);
assert!(v.as_i64().is_err());
Sourcepub fn as_u32(&self) -> Result<u32>
pub fn as_u32(&self) -> Result<u32>
Cast value to [& u32
] if Value::Number
.
Error is raised if the value is not a number or if the numeric value does not fit in a u32.
let v = Value::from(10);
assert_eq!(v.as_u32()?, 10u32);
let v = Value::from(-10);
assert!(v.as_u32().is_err());
Sourcepub fn as_i32(&self) -> Result<i32>
pub fn as_i32(&self) -> Result<i32>
Cast value to [& i32
] if Value::Number
.
Error is raised if the value is not a number or if the numeric value does not fit in a i32.
let v = Value::from(-10);
assert_eq!(v.as_i32()?, -10i32);
let v = Value::from(2_147_483_648i64);
assert!(v.as_i32().is_err());
Sourcepub fn as_u16(&self) -> Result<u16>
pub fn as_u16(&self) -> Result<u16>
Cast value to [& u16
] if Value::Number
.
Error is raised if the value is not a number or if the numeric value does not fit in a u16.
let v = Value::from(10);
assert_eq!(v.as_u16()?, 10u16);
let v = Value::from(-10);
assert!(v.as_u16().is_err());
Sourcepub fn as_i16(&self) -> Result<i16>
pub fn as_i16(&self) -> Result<i16>
Cast value to [& i16
] if Value::Number
.
Error is raised if the value is not a number or if the numeric value does not fit in a i16.
let v = Value::from(-10);
assert_eq!(v.as_i16()?, -10i16);
let v = Value::from(32768i64);
assert!(v.as_i16().is_err());
Sourcepub fn as_u8(&self) -> Result<u8>
pub fn as_u8(&self) -> Result<u8>
Cast value to [& u8
] if Value::Number
.
Error is raised if the value is not a number or if the numeric value does not fit in a u8.
let v = Value::from(10);
assert_eq!(v.as_u8()?, 10u8);
let v = Value::from(-10);
assert!(v.as_u8().is_err());
Sourcepub fn as_i8(&self) -> Result<i8>
pub fn as_i8(&self) -> Result<i8>
Cast value to [& i8
] if Value::Number
.
Error is raised if the value is not a number or if the numeric value does not fit in a i8.
let v = Value::from(-10);
assert_eq!(v.as_i8()?, -10i8);
let v = Value::from(128);
assert!(v.as_i8().is_err());
Sourcepub fn as_f64(&self) -> Result<f64>
pub fn as_f64(&self) -> Result<f64>
Cast value to [& f64
] if Value::Number
.
Error is raised if the value is not a number or if the numeric value
does not fit in a i64.
let v = Value::from(-10);
assert_eq!(v.as_f64()?, -10f64);
let v = Value::from(340_282_366_920_938_463_463_374_607_431_768_211_455u128);
assert!(v.as_i64().is_err());
Sourcepub fn as_string(&self) -> Result<&Rc<str>>
pub fn as_string(&self) -> Result<&Rc<str>>
Cast value to [& Rc<str>
] if Value::String
.
let v = Value::from("Hello");
assert_eq!(v.as_string()?.as_ref(), "Hello");
Sourcepub fn as_string_mut(&mut self) -> Result<&mut Rc<str>>
pub fn as_string_mut(&mut self) -> Result<&mut Rc<str>>
Cast value to [&mut Rc<str>
] if Value::String
.
let mut v = Value::from("Hello");
*v.as_string_mut()? = "World".into();
Sourcepub fn as_array(&self) -> Result<&Vec<Value>>
pub fn as_array(&self) -> Result<&Vec<Value>>
Cast value to [& Vec<Value>
] if Value::Array
.
let v = Value::from([Value::from("Hello")].to_vec());
assert_eq!(v.as_array()?[0], Value::from("Hello"));
Sourcepub fn as_array_mut(&mut self) -> Result<&mut Vec<Value>>
pub fn as_array_mut(&mut self) -> Result<&mut Vec<Value>>
Cast value to [&mut Vec<Value>
] if Value::Array
.
let mut v = Value::from([Value::from("Hello")].to_vec());
v.as_array_mut()?.push(Value::from("World"));
Sourcepub fn as_set(&self) -> Result<&BTreeSet<Value>>
pub fn as_set(&self) -> Result<&BTreeSet<Value>>
Cast value to [& BTreeSet<Value>
] if Value::Set
.
let v = Value::from(
[Value::from("Hello")]
.iter()
.cloned()
.collect::<BTreeSet<Value>>(),
);
assert_eq!(v.as_set()?.first(), Some(&Value::from("Hello")));
Sourcepub fn as_set_mut(&mut self) -> Result<&mut BTreeSet<Value>>
pub fn as_set_mut(&mut self) -> Result<&mut BTreeSet<Value>>
Cast value to [&mut BTreeSet<Value>
] if Value::Set
.
let mut v = Value::from(
[Value::from("Hello")]
.iter()
.cloned()
.collect::<BTreeSet<Value>>(),
);
v.as_set_mut()?.insert(Value::from("World"));
Sourcepub fn as_object(&self) -> Result<&BTreeMap<Value, Value>>
pub fn as_object(&self) -> Result<&BTreeMap<Value, Value>>
Cast value to [& BTreeMap<Value, Value>
] if Value::Object
.
let v = Value::from(
[(Value::from("Hello"), Value::from("World"))]
.iter()
.cloned()
.collect::<BTreeMap<Value, Value>>(),
);
assert_eq!(
v.as_object()?.iter().next(),
Some((&Value::from("Hello"), &Value::from("World"))),
);
Sourcepub fn as_object_mut(&mut self) -> Result<&mut BTreeMap<Value, Value>>
pub fn as_object_mut(&mut self) -> Result<&mut BTreeMap<Value, Value>>
Cast value to [&mut BTreeMap<Value, Value>
] if Value::Object
.
let mut v = Value::from(
[(Value::from("Hello"), Value::from("World"))]
.iter()
.cloned()
.collect::<BTreeMap<Value, Value>>(),
);
v.as_object_mut()?.insert(Value::from("Good"), Value::from("Bye"));
Trait Implementations§
Source§impl From<&str> for Value
impl From<&str> for Value
Source§fn from(s: &str) -> Self
fn from(s: &str) -> Self
Create a Value::String
from &str
.
assert_eq!(Value::from("Hello"), Value::String("Hello".into()));
Source§impl From<BTreeMap<Value, Value>> for Value
impl From<BTreeMap<Value, Value>> for Value
Source§fn from(s: BTreeMap<Value, Value>) -> Self
fn from(s: BTreeMap<Value, Value>) -> Self
Create a Value::Object
from a BTreeMap<Value>
.
let strings = [ ("Hello", "World") ];
let v = Value::from(strings
.iter()
.map(|(k,v)| (Value::from(*k), Value::from(*v)))
.collect::<BTreeMap<Value, Value>>());
let mut iter = v.as_object()?.iter();
assert_eq!(iter.next(), Some((&Value::from(strings[0].0), &Value::from(strings[0].1))));
Source§impl From<BTreeSet<Value>> for Value
impl From<BTreeSet<Value>> for Value
Source§fn from(s: BTreeSet<Value>) -> Self
fn from(s: BTreeSet<Value>) -> Self
Create a Value::Set
from a BTreeSet<Value>
.
let strings = [ "Hello", "World" ];
let v = Value::from(strings
.iter()
.map(|s| Value::from(*s))
.collect::<BTreeSet<Value>>());
let mut iter = v.as_set()?.iter();
assert_eq!(iter.next(), Some(&Value::from(strings[0])));
assert_eq!(iter.next(), Some(&Value::from(strings[1])));
Source§impl From<String> for Value
impl From<String> for Value
Source§fn from(s: String) -> Self
fn from(s: String) -> Self
Create a Value::String
from string
.
assert_eq!(Value::from("Hello".to_string()), Value::String("Hello".into()));
Source§impl From<Value> for Value
impl From<Value> for Value
Source§fn from(v: Value) -> Self
fn from(v: Value) -> Self
Create a Value
from serde_json::Value
.
Returns Value::Undefined
in case of error.
let json_v = serde_json::json!({ "x":10, "y": 20 });
let v = Value::from(json_v);
assert_eq!(v["x"].as_u64()?, 10);
assert_eq!(v["y"].as_u64()?, 20);
Source§impl From<Vec<Value>> for Value
impl From<Vec<Value>> for Value
Source§fn from(a: Vec<Value>) -> Self
fn from(a: Vec<Value>) -> Self
Create a Value::Array
from a Vec<Value>
.
let strings = [ "Hello", "World" ];
let v = Value::from(strings.iter().map(|s| Value::from(*s)).collect::<Vec<Value>>());
assert_eq!(v[0], Value::from(strings[0]));
assert_eq!(v[1], Value::from(strings[1]));
Source§impl From<bool> for Value
impl From<bool> for Value
Source§fn from(b: bool) -> Self
fn from(b: bool) -> Self
Create a Value::Bool
from bool
.
assert_eq!(Value::from(true), Value::Bool(true));
Source§impl From<f64> for Value
impl From<f64> for Value
Source§fn from(n: f64) -> Self
fn from(n: f64) -> Self
Create a Value::Number
from f64
.
assert_eq!(
Value::from(3.141592653589793),
Value::from_numeric_string("3.141592653589793")?);
Note, f64 can store only around 15 digits of precision whereas Value::Number
can store arbitrary precision. Adding an extra digit to the f64 literal in the above
example causes loss of precision and the Value created from f64 does not match the
Value parsed from numeric string (which is more precise).
// The last digit is lost in f64.
assert_ne!(
Value::from(3.1415926535897932),
Value::from_numeric_string("3.141592653589793232")?);
// The value, in this case is equal to parsing the json number with last digit omitted.
assert_ne!(
Value::from(3.1415926535897932),
Value::from_numeric_string("3.14159265358979323")?);
If precision is important, it is better to construct numeric values from strings instead of f64 when possible. See Value::from_numeric_string
Source§impl From<i128> for Value
impl From<i128> for Value
Source§fn from(n: i128) -> Self
fn from(n: i128) -> Self
Create a Value::Number
from i128
.
assert_eq!(
Value::from(-170141183460469231731687303715884105728i128).as_i128()?,
-170141183460469231731687303715884105728i128);
Source§impl From<i32> for Value
impl From<i32> for Value
Source§fn from(n: i32) -> Self
fn from(n: i32) -> Self
Create a Value::Number
from i32
.
assert_eq!(
Value::from(0i32),
Value::from_json_str("0")?);
Source§impl From<i64> for Value
impl From<i64> for Value
Source§fn from(n: i64) -> Self
fn from(n: i64) -> Self
Create a Value::Number
from i64
.
assert_eq!(
Value::from(0i64),
Value::from_json_str("0")?);
Source§impl From<u128> for Value
impl From<u128> for Value
Source§fn from(n: u128) -> Self
fn from(n: u128) -> Self
Create a Value::Number
from u128
.
assert_eq!(
Value::from(340_282_366_920_938_463_463_374_607_431_768_211_455u128).as_u128()?,
340_282_366_920_938_463_463_374_607_431_768_211_455u128);
Source§impl From<u32> for Value
impl From<u32> for Value
Source§fn from(n: u32) -> Self
fn from(n: u32) -> Self
Create a Value::Number
from u32
.
assert_eq!(
Value::from(0u32),
Value::from_json_str("0")?);
Source§impl From<u64> for Value
impl From<u64> for Value
Source§fn from(n: u64) -> Self
fn from(n: u64) -> Self
Create a Value::Number
from u64
.
assert_eq!(
Value::from(0u64),
Value::from_json_str("0")?);
Source§impl From<usize> for Value
impl From<usize> for Value
Source§fn from(n: usize) -> Self
fn from(n: usize) -> Self
Create a Value::Number
from usize
.
assert_eq!(
Value::from(0usize),
Value::from_json_str("0")?);
Source§impl Index<&Value> for Value
impl Index<&Value> for Value
Source§fn index(&self, key: &Value) -> &Self::Output
fn index(&self, key: &Value) -> &Self::Output
Value::Undefined
is returned
- If the index not valid for the collection.
- If the value being indexed is not an array, set or object.
Sets can be indexed only by elements within the set.
let arr = Value::from([Value::from("Hello")].to_vec());
// Index an array.
assert_eq!(arr[&Value::from(0)].as_string()?.as_ref(), "Hello");
assert_eq!(arr[&Value::from(10)], Value::Undefined);
let mut set = Value::new_set();
set.as_set_mut()?.insert(Value::from(100));
set.as_set_mut()?.insert(Value::from("Hello"));
// Index a set.
let item = Value::from("Hello");
assert_eq!(&set[&item], &item);
assert_eq!(&set[&Value::from(10)], &Value::Undefined);
let mut obj = Value::new_object();
obj.as_object_mut()?.insert(Value::from("Hello"), Value::from("World"));
obj.as_object_mut()?.insert(Value::new_array(), Value::from("bye"));
// Index an object.
assert_eq!(&obj[Value::from("Hello")].as_string()?.as_ref(), &"World");
assert_eq!(&obj[Value::from("hllo")], &Value::Undefined);
// Index using non-string key.
assert_eq!(&obj[&Value::new_array()].as_string()?.as_ref(), &"bye");
// Index a non-collection.
assert_eq!(&Value::Null[&Value::from(1)], &Value::Undefined);
This is the preferred way of indexing a value. Since constructing a value may be a costly operation (e.g. Value::String), the caller can construct the index value once and use it many times. `
Source§impl<T> Index<T> for Value
impl<T> Index<T> for Value
Source§fn index(&self, key: T) -> &Self::Output
fn index(&self, key: T) -> &Self::Output
Index a Value
.
A Value
is constructed from the index which is then used for indexing.
let v = Value::from(
[(Value::from("Hello"), Value::from("World")),
(Value::from(1), Value::from(2))]
.iter()
.cloned()
.collect::<BTreeMap<Value, Value>>(),
);
assert_eq!(&v["Hello"].as_string()?.as_ref(), &"World");
assert_eq!(&v[1].as_u64()?, &2u64);