#[derive(Clone, Debug, PartialEq)]
pub enum Value {
    Str(String),
    I64(i64),
    F64(f64),
    Bool(bool),
    Null,
}

impl From<&str> for Value {
    fn from(s: &str) -> Self { Value::Str(s.to_string()) }
}

impl From<String> for Value {
    fn from(s: String) -> Self { Value::Str(s) }
}

impl From<i32> for Value {
    fn from(n: i32) -> Self { Value::I64(n as i64) }
}

impl From<i64> for Value {
    fn from(n: i64) -> Self { Value::I64(n) }
}

impl From<u32> for Value {
    fn from(n: u32) -> Self { Value::I64(n as i64) }
}

impl From<u64> for Value {
    fn from(n: u64) -> Self { Value::I64(n as i64) }
}

impl From<f64> for Value {
    fn from(n: f64) -> Self { Value::F64(n) }
}

impl From<f32> for Value {
    fn from(n: f32) -> Self { Value::F64(n as f64) }
}

impl From<bool> for Value {
    fn from(b: bool) -> Self { Value::Bool(b) }
}

pub fn opt_val<T: Into<Value>>(val: Option<T>) -> Value {
    val.map(Into::into).unwrap_or(Value::Null)
}
