use std::{
collections::{BTreeMap, HashMap},
hash::BuildHasher,
};
use crate::Value;
pub trait JsonMap<V: JsonValue>: IntoIterator<Item = (String, V)> {
fn get(&self, key: &str) -> Option<&V>;
fn get_mut(&mut self, key: &str) -> Option<&mut V>;
fn insert(&mut self, key: String, value: V) -> Option<V>;
fn contains_key(&self, key: &str) -> bool;
fn get_key_value(&self, key: &str) -> Option<(&String, &V)>;
fn remove(&mut self, key: &str) -> Option<V>;
fn remove_entry(&mut self, key: &str) -> Option<(String, V)>;
fn iter<'a>(&'a self) -> impl Iterator<Item = (&'a String, &'a V)>
where
V: 'a;
fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item = (&'a String, &'a mut V)>
where
V: 'a;
}
#[cfg(feature = "serde")]
impl JsonMap<serde_json::Value> for serde_json::Map<String, serde_json::Value> {
fn get(&self, key: &str) -> Option<&serde_json::Value> {
self.get(key)
}
fn get_mut(&mut self, key: &str) -> Option<&mut serde_json::Value> {
self.get_mut(key)
}
fn insert(&mut self, key: String, value: serde_json::Value) -> Option<serde_json::Value> {
self.insert(key, value)
}
fn contains_key(&self, key: &str) -> bool {
self.contains_key(key)
}
fn get_key_value(&self, key: &str) -> Option<(&String, &serde_json::Value)> {
self.get_key_value(key)
}
fn remove(&mut self, key: &str) -> Option<serde_json::Value> {
self.remove(key)
}
fn remove_entry(&mut self, key: &str) -> Option<(String, serde_json::Value)> {
self.remove_entry(key)
}
fn iter<'a>(&'a self) -> impl Iterator<Item = (&'a String, &'a serde_json::Value)>
where
serde_json::Value: 'a,
{
self.iter()
}
fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item = (&'a String, &'a mut serde_json::Value)>
where
serde_json::Value: 'a,
{
self.iter_mut()
}
}
impl<V: JsonValue, S: BuildHasher> JsonMap<V> for HashMap<String, V, S> {
fn get(&self, key: &str) -> Option<&V> {
self.get(key)
}
fn get_mut(&mut self, key: &str) -> Option<&mut V> {
self.get_mut(key)
}
fn insert(&mut self, key: String, value: V) -> Option<V> {
self.insert(key, value)
}
fn contains_key(&self, key: &str) -> bool {
self.contains_key(key)
}
fn get_key_value(&self, key: &str) -> Option<(&String, &V)> {
self.get_key_value(key)
}
fn remove(&mut self, key: &str) -> Option<V> {
self.remove(key)
}
fn remove_entry(&mut self, key: &str) -> Option<(String, V)> {
self.remove_entry(key)
}
fn iter<'a>(&'a self) -> impl Iterator<Item = (&'a String, &'a V)>
where
V: 'a,
{
self.iter()
}
fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item = (&'a String, &'a mut V)>
where
V: 'a,
{
self.iter_mut()
}
}
impl<V: JsonValue> JsonMap<V> for BTreeMap<String, V> {
fn get(&self, key: &str) -> Option<&V> {
self.get(key)
}
fn get_mut(&mut self, key: &str) -> Option<&mut V> {
self.get_mut(key)
}
fn insert(&mut self, key: String, value: V) -> Option<V> {
self.insert(key, value)
}
fn contains_key(&self, key: &str) -> bool {
self.contains_key(key)
}
fn get_key_value(&self, key: &str) -> Option<(&String, &V)> {
self.get_key_value(key)
}
fn remove(&mut self, key: &str) -> Option<V> {
self.remove(key)
}
fn remove_entry(&mut self, key: &str) -> Option<(String, V)> {
self.remove_entry(key)
}
fn iter<'a>(&'a self) -> impl Iterator<Item = (&'a String, &'a V)>
where
V: 'a,
{
self.iter()
}
fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item = (&'a String, &'a mut V)>
where
V: 'a,
{
self.iter_mut()
}
}
pub trait JsonValue: Sized {
type MapType: JsonMap<Self>;
fn null() -> Self;
fn as_object(&self) -> Option<&Self::MapType>;
fn as_object_mut(&mut self) -> Option<&mut Self::MapType>;
fn into_object(self) -> Option<Self::MapType>;
fn as_array(&self) -> Option<&Vec<Self>>;
fn as_array_mut(&mut self) -> Option<&mut Vec<Self>>;
fn into_array(self) -> Option<Vec<Self>>;
fn into_string(self) -> Option<String>;
fn as_str(&self) -> Option<&str>;
fn as_bool(&self) -> Option<bool>;
fn as_u64(&self) -> Option<u64>;
fn as_i64(&self) -> Option<i64>;
fn as_f64(&self) -> Option<f64>;
fn as_null(&self) -> Option<()>;
fn is_object(&self) -> bool {
self.as_object().is_some()
}
fn is_array(&self) -> bool {
self.as_array().is_some()
}
fn is_string(&self) -> bool {
self.as_str().is_some()
}
fn is_bool(&self) -> bool {
self.as_bool().is_some()
}
fn is_u64(&self) -> bool {
self.as_u64().is_some()
}
fn is_i64(&self) -> bool {
self.as_i64().is_some()
}
fn is_f64(&self) -> bool {
self.as_f64().is_some()
}
fn is_null(&self) -> bool {
self.as_null().is_some()
}
}
impl JsonValue for Value<'_> {
type MapType = BTreeMap<String, Self>;
fn null() -> Self {
Value::Null
}
fn as_object(&self) -> Option<&Self::MapType> {
match self {
Value::Object(map) => Some(map),
_ => None,
}
}
fn as_object_mut(&mut self) -> Option<&mut Self::MapType> {
match self {
Value::Object(map) => Some(map),
_ => None,
}
}
fn into_object(self) -> Option<Self::MapType> {
match self {
Value::Object(map) => Some(map),
_ => None,
}
}
fn as_array(&self) -> Option<&Vec<Self>> {
match self {
Value::Array(vec) => Some(vec),
_ => None,
}
}
fn as_array_mut(&mut self) -> Option<&mut Vec<Self>> {
match self {
Value::Array(vec) => Some(vec),
_ => None,
}
}
fn into_array(self) -> Option<Vec<Self>> {
match self {
Value::Array(vec) => Some(vec),
_ => None,
}
}
fn into_string(self) -> Option<String> {
match self {
Value::String(s) => Some(s.into_owned()),
_ => None,
}
}
fn as_str(&self) -> Option<&str> {
match self {
Value::String(s) => Some(s),
_ => None,
}
}
fn as_bool(&self) -> Option<bool> {
match self {
Value::Bool(b) => Some(*b),
_ => None,
}
}
fn as_u64(&self) -> Option<u64> {
match self {
Value::Int(n) if *n >= 0 => Some(*n as u64),
_ => None,
}
}
fn as_i64(&self) -> Option<i64> {
match self {
Value::Int(n) => Some(*n),
_ => None,
}
}
fn as_f64(&self) -> Option<f64> {
match self {
Value::Float(n) => Some(*n),
Value::Int(n) => Some(*n as f64),
_ => None,
}
}
fn as_null(&self) -> Option<()> {
match self {
Value::Null => Some(()),
_ => None,
}
}
}
#[cfg(feature = "serde")]
impl JsonValue for serde_json::Value {
type MapType = serde_json::Map<String, Self>;
fn null() -> Self {
Self::Null
}
fn as_object(&self) -> Option<&Self::MapType> {
self.as_object()
}
fn as_object_mut(&mut self) -> Option<&mut Self::MapType> {
self.as_object_mut()
}
fn into_object(self) -> Option<Self::MapType> {
match self {
Self::Object(map) => Some(map),
_ => None,
}
}
fn as_array(&self) -> Option<&Vec<Self>> {
self.as_array()
}
fn as_array_mut(&mut self) -> Option<&mut Vec<Self>> {
self.as_array_mut()
}
fn into_array(self) -> Option<Vec<Self>> {
match self {
Self::Array(arr) => Some(arr),
_ => None,
}
}
fn into_string(self) -> Option<String> {
match self {
Self::String(s) => Some(s),
_ => None,
}
}
fn as_str(&self) -> Option<&str> {
self.as_str()
}
fn as_bool(&self) -> Option<bool> {
self.as_bool()
}
fn as_u64(&self) -> Option<u64> {
self.as_u64()
}
fn as_i64(&self) -> Option<i64> {
self.as_i64()
}
fn as_f64(&self) -> Option<f64> {
self.as_f64()
}
fn as_null(&self) -> Option<()> {
self.as_null()
}
}