use crate::{value::Index, JsonNumberTrait, JsonPointer, Number};
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[repr(u8)]
pub enum JsonType {
Null = 0,
Boolean = 1,
Number = 2,
String = 3,
Object = 4,
Array = 5,
Raw = 6,
}
impl From<u8> for JsonType {
fn from(value: u8) -> Self {
match value {
0 => JsonType::Null,
1 => JsonType::Boolean,
2 => JsonType::Number,
3 => JsonType::String,
4 => JsonType::Object,
5 => JsonType::Array,
6 => JsonType::Raw,
_ => panic!("invalid JsonType value: {}", value),
}
}
}
pub trait JsonValue: Sized {
type ValueType<'dom>
where
Self: 'dom;
fn get_type(&self) -> JsonType;
#[inline]
fn is_boolean(&self) -> bool {
self.get_type() == JsonType::Boolean
}
#[inline]
fn is_true(&self) -> bool {
self.as_bool().unwrap_or_default()
}
#[inline]
fn is_false(&self) -> bool {
!self.is_true()
}
#[inline]
fn is_null(&self) -> bool {
self.get_type() == JsonType::Null
}
#[inline]
fn is_number(&self) -> bool {
self.get_type() == JsonType::Number
}
#[inline]
fn is_str(&self) -> bool {
self.get_type() == JsonType::String
}
#[inline]
fn is_array(&self) -> bool {
self.get_type() == JsonType::Array
}
#[inline]
fn is_object(&self) -> bool {
self.get_type() == JsonType::Object
}
#[inline]
fn is_f64(&self) -> bool {
self.as_f64().is_some()
}
#[inline]
fn is_i64(&self) -> bool {
self.as_i64().is_some()
}
#[inline]
fn is_u64(&self) -> bool {
self.as_u64().is_some()
}
#[inline]
fn as_i64(&self) -> Option<i64> {
self.as_number().and_then(|n| n.as_i64())
}
#[inline]
fn as_u64(&self) -> Option<u64> {
self.as_number().and_then(|n| n.as_u64())
}
#[inline]
fn as_f64(&self) -> Option<f64> {
self.as_number().and_then(|n| n.as_f64())
}
fn as_number(&self) -> Option<Number>;
fn as_str(&self) -> Option<&str>;
fn as_bool(&self) -> Option<bool>;
fn get<I: Index>(&self, index: I) -> Option<Self::ValueType<'_>>;
fn pointer(&self, path: &JsonPointer) -> Option<Self::ValueType<'_>>;
}
impl<V: JsonValue> JsonValue for Option<V> {
type ValueType<'dom> = V::ValueType<'dom>
where
V:'dom, Self: 'dom;
fn as_bool(&self) -> Option<bool> {
self.as_ref().and_then(|v| v.as_bool())
}
fn as_f64(&self) -> Option<f64> {
self.as_ref().and_then(|v| v.as_f64())
}
fn as_i64(&self) -> Option<i64> {
self.as_ref().and_then(|v| v.as_i64())
}
fn as_u64(&self) -> Option<u64> {
self.as_ref().and_then(|v| v.as_u64())
}
fn as_number(&self) -> Option<Number> {
self.as_ref().and_then(|v| v.as_number())
}
fn get_type(&self) -> JsonType {
self.as_ref().map_or(JsonType::Null, |v| v.get_type())
}
fn as_str(&self) -> Option<&str> {
self.as_ref().and_then(|v| v.as_str())
}
fn get<I: Index>(&self, index: I) -> Option<Self::ValueType<'_>> {
self.as_ref().and_then(|v| v.get(index))
}
fn pointer(&self, path: &JsonPointer) -> Option<Self::ValueType<'_>> {
self.as_ref().and_then(|v| v.pointer(path))
}
}
impl<V: JsonValue, E> JsonValue for Result<V, E> {
type ValueType<'dom> = V::ValueType<'dom>
where
V:'dom, Self: 'dom;
fn as_bool(&self) -> Option<bool> {
self.as_ref().ok().and_then(|v| v.as_bool())
}
fn as_f64(&self) -> Option<f64> {
self.as_ref().ok().and_then(|v| v.as_f64())
}
fn as_i64(&self) -> Option<i64> {
self.as_ref().ok().and_then(|v| v.as_i64())
}
fn as_u64(&self) -> Option<u64> {
self.as_ref().ok().and_then(|v| v.as_u64())
}
fn as_number(&self) -> Option<Number> {
self.as_ref().ok().and_then(|v| v.as_number())
}
fn get_type(&self) -> JsonType {
self.as_ref().ok().map_or(JsonType::Null, |v| v.get_type())
}
fn as_str(&self) -> Option<&str> {
self.as_ref().ok().and_then(|v| v.as_str())
}
fn get<I: Index>(&self, index: I) -> Option<Self::ValueType<'_>> {
self.as_ref().ok().and_then(|v| v.get(index))
}
fn pointer(&self, path: &JsonPointer) -> Option<Self::ValueType<'_>> {
self.as_ref().ok().and_then(|v| v.pointer(path))
}
}
impl<V: JsonValue> JsonValue for &V {
type ValueType<'dom> = V::ValueType<'dom>
where
V:'dom, Self: 'dom;
fn as_bool(&self) -> Option<bool> {
(*self).as_bool()
}
fn as_f64(&self) -> Option<f64> {
(*self).as_f64()
}
fn as_i64(&self) -> Option<i64> {
(*self).as_i64()
}
fn as_u64(&self) -> Option<u64> {
(*self).as_u64()
}
fn as_number(&self) -> Option<Number> {
(*self).as_number()
}
fn get_type(&self) -> JsonType {
(*self).get_type()
}
fn as_str(&self) -> Option<&str> {
(*self).as_str()
}
fn get<I: Index>(&self, index: I) -> Option<Self::ValueType<'_>> {
(*self).get(index)
}
fn pointer(&self, path: &JsonPointer) -> Option<Self::ValueType<'_>> {
(*self).pointer(path)
}
}
impl<V: JsonValue> JsonValue for &mut V {
type ValueType<'dom> = V::ValueType<'dom>
where
V:'dom, Self: 'dom;
fn as_bool(&self) -> Option<bool> {
(**self).as_bool()
}
fn as_f64(&self) -> Option<f64> {
(**self).as_f64()
}
fn as_i64(&self) -> Option<i64> {
(**self).as_i64()
}
fn as_u64(&self) -> Option<u64> {
(**self).as_u64()
}
fn as_number(&self) -> Option<Number> {
(**self).as_number()
}
fn get_type(&self) -> JsonType {
(**self).get_type()
}
fn as_str(&self) -> Option<&str> {
(**self).as_str()
}
fn get<I: Index>(&self, index: I) -> Option<Self::ValueType<'_>> {
(**self).get(index)
}
fn pointer(&self, path: &JsonPointer) -> Option<Self::ValueType<'_>> {
(**self).pointer(path)
}
}