use std::{
convert::{From, TryFrom, TryInto},
string::String
};
use crate::{
error::Error,
sd::{Array, Object},
Result
};
#[derive(PartialEq, Clone)]
pub enum Value
{
Null,
Bool(bool),
Uint8(u8),
Uint16(u16),
Uint32(u32),
Uint64(u64),
Int8(i8),
Int16(i16),
Int32(i32),
Int64(i64),
Float(f32),
Double(f64),
String(String),
Array(Array),
Object(Object)
}
impl Value
{
pub fn get_type_name(&self) -> &'static str
{
return match self {
Value::Null => "null",
Value::Bool(_) => "bool",
Value::Uint8(_) => "uint8",
Value::Uint16(_) => "uint16",
Value::Uint32(_) => "uint32",
Value::Uint64(_) => "uint64",
Value::Int8(_) => "int8",
Value::Int16(_) => "int16",
Value::Int32(_) => "int32",
Value::Int64(_) => "int64",
Value::Float(_) => "float",
Value::Double(_) => "double",
Value::String(_) => "string",
Value::Array(_) => "array",
Value::Object(_) => "object"
};
}
}
impl From<bool> for Value
{
fn from(v: bool) -> Self
{
return Value::Bool(v);
}
}
impl From<u8> for Value
{
fn from(v: u8) -> Self
{
return Value::Uint8(v);
}
}
impl From<u16> for Value
{
fn from(v: u16) -> Self
{
return Value::Uint16(v);
}
}
impl From<u32> for Value
{
fn from(v: u32) -> Self
{
return Value::Uint32(v);
}
}
impl From<u64> for Value
{
fn from(v: u64) -> Self
{
return Value::Uint64(v);
}
}
impl From<i8> for Value
{
fn from(v: i8) -> Self
{
return Value::Int8(v);
}
}
impl From<i16> for Value
{
fn from(v: i16) -> Self
{
return Value::Int16(v);
}
}
impl From<i32> for Value
{
fn from(v: i32) -> Self
{
return Value::Int32(v);
}
}
impl From<i64> for Value
{
fn from(v: i64) -> Self
{
return Value::Int64(v);
}
}
impl From<f32> for Value
{
fn from(v: f32) -> Self
{
return Value::Float(v);
}
}
impl From<f64> for Value
{
fn from(v: f64) -> Self
{
return Value::Double(v);
}
}
impl From<&str> for Value
{
fn from(v: &str) -> Self
{
return Value::String(String::from(v));
}
}
impl From<String> for Value
{
fn from(v: String) -> Self
{
return Value::String(v);
}
}
impl From<Array> for Value
{
fn from(v: Array) -> Self
{
return Value::Array(v);
}
}
impl From<Object> for Value
{
fn from(v: Object) -> Self
{
return Value::Object(v);
}
}
impl<T: Into<Value>> From<Option<T>> for Value
{
fn from(v: Option<T>) -> Self
{
if let Some(v) = v {
return v.into();
}
return Value::Null;
}
}
impl<T: Into<Value>> From<Vec<T>> for Value
{
fn from(v: Vec<T>) -> Self
{
let mut arr = Array::new();
for v1 in v {
arr.add(v1.into());
}
return Value::Array(arr);
}
}
impl TryFrom<Value> for bool
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
if let Value::Bool(v) = v {
return Ok(v);
}
return Err(Error::TypeError("bool", v.get_type_name()));
}
}
impl TryFrom<Value> for u8
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
if let Value::Uint8(v) = v {
return Ok(v);
}
return Err(Error::TypeError("uint8", v.get_type_name()));
}
}
impl TryFrom<Value> for u16
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
return match v {
Value::Uint16(v) => Ok(v),
Value::Uint8(v) => Ok(v as u16),
_ => Err(Error::TypeError("uint8 or uint16", v.get_type_name()))
};
}
}
impl TryFrom<Value> for u32
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
return match v {
Value::Uint32(v) => Ok(v),
Value::Uint16(v) => Ok(v as u32),
Value::Uint8(v) => Ok(v as u32),
_ => Err(Error::TypeError("uint8, uint16 or uint32", v.get_type_name()))
};
}
}
impl TryFrom<Value> for u64
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
return match v {
Value::Uint64(v) => Ok(v),
Value::Uint32(v) => Ok(v as u64),
Value::Uint16(v) => Ok(v as u64),
Value::Uint8(v) => Ok(v as u64),
_ => Err(Error::TypeError("uint8, uint16, uint32 or uint64", v.get_type_name()))
};
}
}
impl TryFrom<Value> for i8
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
if let Value::Int8(v) = v {
return Ok(v);
}
return Err(Error::TypeError("int8", v.get_type_name()));
}
}
impl TryFrom<Value> for i16
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
return match v {
Value::Int16(v) => Ok(v),
Value::Int8(v) => Ok(v as i16),
_ => Err(Error::TypeError("int8 or int16", v.get_type_name()))
};
}
}
impl TryFrom<Value> for i32
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
return match v {
Value::Int32(v) => Ok(v),
Value::Int16(v) => Ok(v as i32),
Value::Int8(v) => Ok(v as i32),
_ => Err(Error::TypeError("int8, int16 or int32", v.get_type_name()))
};
}
}
impl TryFrom<Value> for i64
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
return match v {
Value::Int64(v) => Ok(v),
Value::Int32(v) => Ok(v as i64),
Value::Int16(v) => Ok(v as i64),
Value::Int8(v) => Ok(v as i64),
_ => Err(Error::TypeError("int8, int16, int32 or int64", v.get_type_name()))
};
}
}
impl TryFrom<Value> for f32
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
if let Value::Float(v) = v {
return Ok(v);
}
return Err(Error::TypeError("float", v.get_type_name()));
}
}
impl TryFrom<Value> for f64
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
return match v {
Value::Double(v) => Ok(v),
Value::Float(v) => Ok(v as f64),
_ => Err(Error::TypeError("float or double", v.get_type_name()))
};
}
}
impl TryFrom<Value> for String
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
if let Value::String(v) = v {
return Ok(v);
}
return Err(Error::TypeError("string", v.get_type_name()));
}
}
impl TryFrom<Value> for Array
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
if let Value::Array(v) = v {
return Ok(v);
}
return Err(Error::TypeError("array", v.get_type_name()));
}
}
impl TryFrom<Value> for Object
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
if let Value::Object(v) = v {
return Ok(v);
}
return Err(Error::TypeError("object", v.get_type_name()));
}
}
impl TryFrom<&Value> for bool
{
type Error = Error;
fn try_from(v: &Value) -> Result<Self>
{
if let Value::Bool(v) = v {
return Ok(*v);
}
return Err(Error::TypeError("bool", v.get_type_name()));
}
}
impl TryFrom<&Value> for u8
{
type Error = Error;
fn try_from(v: &Value) -> Result<Self>
{
if let Value::Uint8(v) = v {
return Ok(*v);
}
return Err(Error::TypeError("uint8", v.get_type_name()));
}
}
impl TryFrom<&Value> for u16
{
type Error = Error;
fn try_from(v: &Value) -> Result<Self>
{
return match v {
Value::Uint16(v) => Ok(*v),
Value::Uint8(v) => Ok(*v as u16),
_ => Err(Error::TypeError("uint8 or uint16", v.get_type_name()))
};
}
}
impl TryFrom<&Value> for u32
{
type Error = Error;
fn try_from(v: &Value) -> Result<Self>
{
return match v {
Value::Uint32(v) => Ok(*v),
Value::Uint16(v) => Ok(*v as u32),
Value::Uint8(v) => Ok(*v as u32),
_ => Err(Error::TypeError("uint8, uint16 or uint32", v.get_type_name()))
};
}
}
impl TryFrom<&Value> for u64
{
type Error = Error;
fn try_from(v: &Value) -> Result<Self>
{
return match v {
Value::Uint64(v) => Ok(*v),
Value::Uint32(v) => Ok(*v as u64),
Value::Uint16(v) => Ok(*v as u64),
Value::Uint8(v) => Ok(*v as u64),
_ => Err(Error::TypeError("uint8, uint16, uint32 or uint64", v.get_type_name()))
};
}
}
impl TryFrom<&Value> for i8
{
type Error = Error;
fn try_from(v: &Value) -> Result<Self>
{
if let Value::Int8(v) = v {
return Ok(*v);
}
return Err(Error::TypeError("int8", v.get_type_name()));
}
}
impl TryFrom<&Value> for i16
{
type Error = Error;
fn try_from(v: &Value) -> Result<Self>
{
return match v {
Value::Int16(v) => Ok(*v),
Value::Int8(v) => Ok(*v as i16),
_ => Err(Error::TypeError("int8 or int16", v.get_type_name()))
};
}
}
impl TryFrom<&Value> for i32
{
type Error = Error;
fn try_from(v: &Value) -> Result<Self>
{
return match v {
Value::Int32(v) => Ok(*v),
Value::Int16(v) => Ok(*v as i32),
Value::Int8(v) => Ok(*v as i32),
_ => Err(Error::TypeError("int8, int16 or int32", v.get_type_name()))
};
}
}
impl TryFrom<&Value> for i64
{
type Error = Error;
fn try_from(v: &Value) -> Result<Self>
{
return match v {
Value::Int64(v) => Ok(*v),
Value::Int32(v) => Ok(*v as i64),
Value::Int16(v) => Ok(*v as i64),
Value::Int8(v) => Ok(*v as i64),
_ => Err(Error::TypeError("int8, int16, int32 or int64", v.get_type_name()))
};
}
}
impl TryFrom<&Value> for f32
{
type Error = Error;
fn try_from(v: &Value) -> Result<Self>
{
if let Value::Float(v) = v {
return Ok(*v);
}
return Err(Error::TypeError("float", v.get_type_name()));
}
}
impl TryFrom<&Value> for f64
{
type Error = Error;
fn try_from(v: &Value) -> Result<Self>
{
return match v {
Value::Double(v) => Ok(*v),
Value::Float(v) => Ok(*v as f64),
_ => Err(Error::TypeError("float or double", v.get_type_name()))
};
}
}
impl<'a> TryFrom<&'a Value> for &'a str
{
type Error = Error;
fn try_from(v: &'a Value) -> Result<Self>
{
if let Value::String(v) = v {
return Ok(&v);
}
return Err(Error::TypeError("string", v.get_type_name()));
}
}
impl<'a> TryFrom<&'a Value> for &'a Array
{
type Error = Error;
fn try_from(v: &'a Value) -> Result<Self>
{
if let Value::Array(v) = v {
return Ok(&v);
}
return Err(Error::TypeError("array", v.get_type_name()));
}
}
impl<'a> TryFrom<&'a Value> for &'a Object
{
type Error = Error;
fn try_from(v: &'a Value) -> Result<Self>
{
if let Value::Object(v) = v {
return Ok(v);
}
return Err(Error::TypeError("object", v.get_type_name()));
}
}
macro_rules! generate_option_try_from {
($($t:ident)*) => {
$(
impl TryFrom<Value> for Option<$t>
{
type Error = Error;
fn try_from(v: Value) -> Result<Self>
{
if let Value::Null = v
{
return Ok(None);
}
let v = v.try_into()?;
return Ok(Some(v));
}
}
)*
};
}
macro_rules! generate_option_try_from_ref {
($($t:ident)*) => {
$(
impl <'a> TryFrom<&'a Value> for Option<&'a $t>
{
type Error = Error;
fn try_from(v: &'a Value) -> Result<Self>
{
if let Value::Null = v
{
return Ok(None);
}
let v = v.try_into()?;
return Ok(Some(v));
}
}
)*
};
}
macro_rules! generate_option_try_from_ref_scalar {
($($t:ident)*) => {
$(
impl <'a> TryFrom<&'a Value> for Option<$t>
{
type Error = Error;
fn try_from(v: &'a Value) -> Result<Self>
{
if let Value::Null = v
{
return Ok(None);
}
let v = v.try_into()?;
return Ok(Some(v));
}
}
)*
};
}
generate_option_try_from! {
u8 u16 u32 u64
i8 i16 i32 i64
f32 f64 bool
String Array Object
}
generate_option_try_from_ref! {
Array Object str
}
generate_option_try_from_ref_scalar! {
u8 u16 u32 u64
i8 i16 i32 i64
f32 f64 bool
}