pub(crate) use deserializer::ValueDeserializer;
use std::collections::{hash_map::Entry, HashMap};
use crate::value::number::Number;
pub mod deserializer;
pub mod serializer;
pub mod number;
mod serialize;
mod deserialize;
#[derive(Debug, Clone)]
pub enum Value {
String(String),
Bool(bool),
Number(Number),
None,
Map(HashMap<String, Value>),
Array(Vec<Value>),
}
impl Value {
pub fn merge(&mut self, merge_value: Value) {
match (self, merge_value) {
(Value::Map(ref mut self_map), Value::Map(merge_map)) => {
for (k, v) in merge_map {
match self_map.entry(k) {
Entry::Occupied(mut occupied) => {
occupied.get_mut().merge(v);
}
Entry::Vacant(vacant) => {
vacant.insert(v);
}
}
}
}
(self_value, merge_value) => *self_value = merge_value,
}
}
pub fn get(&self, key: &str) -> Option<&Value> {
if key.is_empty() {
return Some(self);
}
key.split('.').try_fold(self, |target, key| match target {
Value::Map(map) => map.get(key),
_ => None,
})
}
pub fn get_mut_or_create(&mut self, key: &str) -> &mut Value {
if key.is_empty() {
return self;
}
key.split('.').fold(self, |target, key| match target {
Value::Map(map) => map.entry(key.to_string()).or_insert(Value::None),
value => {
*value = Value::Map(HashMap::new());
match value {
Value::Map(map) => map.entry(key.to_string()).or_insert(Value::None),
_ => unreachable!(),
}
}
})
}
}
impl PartialEq for Value {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Value::String(v1), Value::String(v2)) => v1 == v2,
(Value::Bool(v1), Value::Bool(v2)) => v1 == v2,
(Value::Number(v1), Value::Number(v2)) => v1 == v2,
(Value::None, Value::None) => true,
(Value::Map(v1), Value::Map(v2)) => v1 == v2,
(Value::Array(v1), Value::Array(v2)) => v1 == v2,
_ => false,
}
}
}
impl From<bool> for Value {
fn from(value: bool) -> Self {
Value::Bool(value)
}
}
impl From<()> for Value {
fn from(_: ()) -> Self {
Value::None
}
}
impl From<&str> for Value {
fn from(value: &str) -> Value {
Value::String(value.to_string())
}
}
impl From<String> for Value {
fn from(value: String) -> Value {
Value::String(value)
}
}
impl From<char> for Value {
fn from(value: char) -> Value {
Value::String(value.to_string())
}
}
impl From<u8> for Value {
fn from(value: u8) -> Self {
Value::Number(value.into())
}
}
impl From<u16> for Value {
fn from(value: u16) -> Self {
Value::Number(value.into())
}
}
impl From<u32> for Value {
fn from(value: u32) -> Self {
Value::Number(value.into())
}
}
impl From<u64> for Value {
fn from(value: u64) -> Self {
Value::Number(value.into())
}
}
impl From<i8> for Value {
fn from(value: i8) -> Self {
Value::Number(value.into())
}
}
impl From<i16> for Value {
fn from(value: i16) -> Self {
Value::Number(value.into())
}
}
impl From<i32> for Value {
fn from(value: i32) -> Self {
Value::Number(value.into())
}
}
impl From<i64> for Value {
fn from(value: i64) -> Self {
Value::Number(value.into())
}
}
impl From<f32> for Value {
fn from(value: f32) -> Self {
Value::Number(value.into())
}
}
impl From<f64> for Value {
fn from(value: f64) -> Self {
Value::Number(value.into())
}
}
impl<R: ToString, T: Into<Value>> From<HashMap<R, T>> for Value {
fn from(value: HashMap<R, T>) -> Self {
Value::Map(
value
.into_iter()
.map(|(k, v)| (k.to_string(), v.into()))
.collect(),
)
}
}
impl<T: Into<Value>> From<Vec<T>> for Value {
fn from(value: Vec<T>) -> Self {
Value::Array(value.into_iter().map(|v| v.into()).collect())
}
}
impl<T: Into<Value>> From<Option<T>> for Value {
fn from(v: Option<T>) -> Self {
match v {
None => Value::None,
Some(v) => v.into(),
}
}
}