mod string;
use core::{
mem::replace,
ops::{Index, IndexMut},
};
use crate::{
pointer::JsonPointer,
value::{misc::define_value, owned},
};
pub use string::String;
define_value! {
name: Value<'a>,
string: String<'a>,
lifetime: 'a,
volatility: NonVolatile,
}
impl<'a> Value<'a> {
#[inline]
pub fn take(&mut self) -> Value<'a> {
replace(self, Value::Null)
}
#[inline]
pub fn get<I: JsonPointer>(&self, idx: I) -> Option<&Value<'a>> {
match self {
Value::Array(v) => v.get(idx.as_index()?),
Value::Object(v) => v.get(idx.as_key()?),
_ => None,
}
}
#[inline]
pub fn get_mut<I: JsonPointer>(&mut self, idx: I) -> Option<&mut Value<'a>> {
match self {
Value::Array(v) => v.get_mut(idx.as_index()?),
Value::Object(v) => v.get_mut(idx.as_key()?),
_ => None,
}
}
#[inline]
pub fn as_null(&self) -> Option<()> {
match self {
Self::Null => Some(()),
_ => None,
}
}
#[inline]
pub fn as_bool(&self) -> Option<bool> {
match self {
Self::Boolean(v) => Some(*v),
_ => None,
}
}
#[inline]
pub fn as_array(&self) -> Option<&Array<Value<'a>>> {
Some(match self {
Self::Array(v) => v,
_ => return None,
})
}
#[inline]
pub fn as_array_mut(&mut self) -> Option<&mut Array<Value<'a>>> {
Some(match self {
Self::Array(v) => v,
_ => return None,
})
}
#[inline]
pub fn as_object(&self) -> Option<&Object<String<'a>, Value<'a>>> {
Some(match self {
Self::Object(v) => v,
_ => return None,
})
}
#[inline]
pub fn as_object_mut(&mut self) -> Option<&mut Object<String<'a>, Value<'a>>> {
Some(match self {
Self::Object(v) => v,
_ => return None,
})
}
#[inline]
pub fn as_number(&self) -> Option<Number> {
Some(match *self {
Self::Number(v) => v,
_ => return None,
})
}
#[inline]
pub fn as_i64(&self) -> Option<i64> {
self.as_number()?.as_i64()
}
#[inline]
pub fn as_u64(&self) -> Option<u64> {
self.as_number()?.as_u64()
}
#[inline]
pub fn as_f64(&self) -> Option<f64> {
self.as_number()?.as_f64()
}
#[inline]
pub fn as_str(&self) -> Option<&str> {
Some(match self {
Self::String(v) => v,
_ => return None,
})
}
#[inline]
pub fn is_str(&self) -> bool {
self.as_str().is_some()
}
#[inline]
pub fn is_null(&self) -> bool {
self.as_null().is_some()
}
#[inline]
pub fn is_bool(&self) -> bool {
self.as_bool().is_some()
}
#[inline]
pub fn is_array(&self) -> bool {
self.as_array().is_some()
}
#[inline]
pub fn is_object(&self) -> bool {
self.as_object().is_some()
}
#[inline]
pub fn is_number(&self) -> bool {
self.as_number().is_some()
}
#[inline]
pub fn is_i64(&self) -> bool {
self.as_i64().is_some()
}
#[inline]
pub fn is_u64(&self) -> bool {
self.as_u64().is_some()
}
#[inline]
pub fn is_f64(&self) -> bool {
self.as_f64().is_some()
}
pub fn pointer<P>(&self, p: P) -> Option<&Value<'a>>
where
P: IntoIterator,
P::Item: JsonPointer,
{
let mut tmp = self;
for pointer in p {
tmp = match tmp {
Value::Object(obj) => obj.get(pointer.as_key()?),
Value::Array(arr) => arr.get(pointer.as_index()?),
_ => None,
}?
}
Some(tmp)
}
pub fn pointer_mut<P>(&mut self, p: P) -> Option<&mut Value<'a>>
where
P: IntoIterator,
P::Item: JsonPointer,
{
let mut tmp = self;
for pointer in p {
tmp = match tmp {
Value::Object(obj) => obj.get_mut(pointer.as_key()?),
Value::Array(arr) => arr.get_mut(pointer.as_index()?),
_ => None,
}?
}
Some(tmp)
}
}
impl PartialEq<Value<'_>> for owned::Value {
fn eq(&self, other: &Value<'_>) -> bool {
match (self, other) {
(Self::Null, Value::Null) => true,
(Self::Number(a), Value::Number(b)) => a == b,
(Self::String(a), Value::String(b)) => a == b,
(Self::Boolean(a), Value::Boolean(b)) => a == b,
(Self::Array(a), Value::Array(b)) => **a == **b,
(Self::Object(a), Value::Object(b)) => {
a.len() == b.len()
&& a.as_slice()
.iter()
.zip(b.as_slice())
.all(|((a, b), (x, y))| a == x && b == y)
}
_ => false,
}
}
}
impl PartialEq<owned::Value> for Value<'_> {
#[inline]
fn eq(&self, other: &owned::Value) -> bool {
other == self
}
}
impl<'a> Index<usize> for Value<'a> {
type Output = Value<'a>;
#[inline]
fn index(&self, idx: usize) -> &Self::Output {
match self.as_array() {
Some(v) => match v.get(idx) {
Some(v) => v,
_ => panic!("given index does not exist in the array"),
},
_ => panic!("value is not an array"),
}
}
}
impl IndexMut<usize> for Value<'_> {
#[inline]
fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
match self.as_array_mut() {
Some(v) => match v.get_mut(idx) {
Some(v) => v,
_ => panic!("given index does not exist in the array"),
},
_ => panic!("value is not an array"),
}
}
}
impl<'a> Index<&str> for Value<'a> {
type Output = Value<'a>;
#[inline]
fn index(&self, key: &str) -> &Self::Output {
match self.as_object() {
Some(v) => match v.get(key) {
Some(v) => v,
_ => panic!("given key does not exist in the object"),
},
_ => panic!("value is not an object"),
}
}
}
impl IndexMut<&str> for Value<'_> {
#[inline]
fn index_mut(&mut self, key: &str) -> &mut Self::Output {
match self.as_object_mut() {
Some(v) => match v.get_mut(key) {
Some(v) => v,
_ => panic!("given key does not exist in the object"),
},
_ => panic!("value is not an object"),
}
}
}