use std::collections::HashMap;
use std::iter::FromIterator;
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
Null,
Bool(bool),
Number(f64),
String(String),
Array(Vec<Value>),
Object(HashMap<String, Value>),
}
macro_rules! impl_from_num_for_value {
( $( $t:ty ),* ) => {
$(
impl From<$t> for Value {
fn from(n: $t) -> Self {
Value::Number(n as f64)
}
}
)*
};
}
impl_from_num_for_value!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize, f32, f64);
impl From<bool> for Value {
fn from(b: bool) -> Self {
Value::Bool(b)
}
}
impl From<String> for Value {
fn from(s: String) -> Self {
Value::String(s)
}
}
impl From<&str> for Value {
fn from(s: &str) -> Self {
Value::String(s.to_string())
}
}
impl<T: Into<Value>> From<Vec<T>> for Value {
fn from(arr: Vec<T>) -> Self {
Value::Array(arr.into_iter().map(Into::into).collect())
}
}
impl<K: Into<String>, V: Into<Value>> From<HashMap<K, V>> for Value {
fn from(map: HashMap<K, V>) -> Self {
Value::Object(
map.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect(),
)
}
}
impl<K: Into<String>, V: Into<Value>> FromIterator<(K, V)> for Value {
fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
Value::Object(
iter.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect(),
)
}
}