use crate::indexing::Index;
use std::hash::Hash;
#[derive(Clone, Debug)]
pub enum Value {
Null,
Bool(bool),
Number(f64),
String(String),
Array(Vec<Value>),
Object(Vec<(String, Value)>),
}
impl Value {
pub fn get<I>(&self, index: I) -> Option<&Value>
where
I: Index,
{
index.json_index(self)
}
pub fn get_mut<I>(&mut self, index: I) -> Option<&mut Value>
where
I: Index,
{
index.json_index_mut(self)
}
pub fn as_bool(&self) -> Option<bool> {
match self {
Value::Bool(b) => Some(*b),
_ => None,
}
}
pub fn as_number(&self) -> Option<f64> {
match self {
Value::Number(n) => Some(*n),
_ => None,
}
}
pub fn as_str(&self) -> Option<&str> {
match self {
Value::String(s) => Some(s.as_str()),
_ => None,
}
}
pub fn as_array(&self) -> Option<&Vec<Value>> {
match self {
Value::Array(a) => Some(a),
_ => None,
}
}
pub fn as_object(&self) -> Option<&Vec<(String, Value)>> {
match self {
Value::Object(o) => Some(o),
_ => None,
}
}
}
impl PartialEq for Value {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Bool(l0), Self::Bool(r0)) => *l0 == *r0,
(Self::Number(l0), Self::Number(r0)) => *l0 == *r0,
(Self::String(l0), Self::String(r0)) => *l0 == *r0,
(Self::Array(l0), Self::Array(r0)) => *l0 == *r0,
(Self::Object(l0), Self::Object(r0)) => *l0 == *r0,
(Self::Null, Self::Null) => true,
_ => false,
}
}
}
impl Eq for Value {}
impl Hash for Value {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
core::mem::discriminant(self).hash(state);
match self {
Self::Bool(b) => b.hash(state),
Self::Number(n) => (n.to_bits()).hash(state),
Self::String(s) => s.hash(state),
Self::Array(a) => a.hash(state),
Self::Object(o) => o.hash(state),
Self::Null => (),
}
}
}