use std::fmt::Display;
use crate::pointer::JsonPointerSegment;
pub enum JsonTreeValue<'a, T: ?Sized> {
Base(&'a T, &'a dyn Display, BaseValueType),
Expandable(Vec<(JsonPointerSegment<'a>, &'a T)>, ExpandableType),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BaseValueType {
Null,
Bool,
Number,
String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ExpandableType {
Array,
Object,
}
pub trait ToJsonTreeValue {
fn to_json_tree_value(&self) -> JsonTreeValue<'_, Self>;
fn is_expandable(&self) -> bool;
}
#[cfg(feature = "serde_json")]
impl ToJsonTreeValue for serde_json::Value {
fn to_json_tree_value(&self) -> JsonTreeValue<'_, Self> {
match self {
serde_json::Value::Null => JsonTreeValue::Base(self, self, BaseValueType::Null),
serde_json::Value::Bool(b) => JsonTreeValue::Base(self, b, BaseValueType::Bool),
serde_json::Value::Number(n) => JsonTreeValue::Base(self, n, BaseValueType::Number),
serde_json::Value::String(s) => JsonTreeValue::Base(self, s, BaseValueType::String),
serde_json::Value::Array(arr) => JsonTreeValue::Expandable(
arr.iter()
.enumerate()
.map(|(idx, elem)| (JsonPointerSegment::Index(idx), elem))
.collect(),
ExpandableType::Array,
),
serde_json::Value::Object(obj) => JsonTreeValue::Expandable(
obj.iter()
.map(|(key, val)| (JsonPointerSegment::Key(key), val))
.collect(),
ExpandableType::Object,
),
}
}
fn is_expandable(&self) -> bool {
matches!(
self,
serde_json::Value::Array(_) | serde_json::Value::Object(_)
)
}
}
#[cfg(feature = "simd_json")]
impl ToJsonTreeValue for simd_json::owned::Value {
fn to_json_tree_value(&self) -> JsonTreeValue<'_, Self> {
match self {
simd_json::OwnedValue::Static(s) => match s {
simd_json::StaticNode::I64(n) => {
JsonTreeValue::Base(self, n, BaseValueType::Number)
}
simd_json::StaticNode::U64(n) => {
JsonTreeValue::Base(self, n, BaseValueType::Number)
}
simd_json::StaticNode::F64(n) => {
JsonTreeValue::Base(self, n, BaseValueType::Number)
}
simd_json::StaticNode::Bool(b) => JsonTreeValue::Base(self, b, BaseValueType::Bool),
simd_json::StaticNode::Null => JsonTreeValue::Base(self, self, BaseValueType::Null),
},
simd_json::OwnedValue::String(s) => JsonTreeValue::Base(self, s, BaseValueType::String),
simd_json::OwnedValue::Array(arr) => JsonTreeValue::Expandable(
arr.iter()
.enumerate()
.map(|(idx, elem)| (JsonPointerSegment::Index(idx), elem))
.collect(),
ExpandableType::Array,
),
simd_json::OwnedValue::Object(obj) => JsonTreeValue::Expandable(
obj.iter()
.map(|(key, val)| (JsonPointerSegment::Key(key), val))
.collect(),
ExpandableType::Object,
),
}
}
fn is_expandable(&self) -> bool {
matches!(
self,
simd_json::owned::Value::Array(_) | simd_json::owned::Value::Object(_)
)
}
}