shinyframework_configuration 0.1.2

Shiny Configuration
Documentation
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(),
        }
    }
}