use std::borrow::Cow;
use std::cmp;
use serde::{Serialize, Deserialize};
use list::List;
use table::Table;
use error::Error;
use ser::ValueSerializer;
#[derive(Debug, Clone, PartialEq)]
pub enum Value<'a> {
Null,
Bool(bool),
I64(i64),
F64(f64),
Bytes(Box<Cow<'a, [u8]>>),
String(Box<Cow<'a, str>>),
List(Box<Cow<'a, List<'a>>>),
Table(Box<Cow<'a, Table<'a>>>),
}
impl<'a> Value<'a> {
pub fn serialize<T>(value: &T) -> Result<Value<'static>, Error>
where
T: Serialize + ?Sized,
{
value.serialize(ValueSerializer)
}
pub fn deserialize<'b: 'a, T>(&'b self) -> Result<T, Error>
where
T: Deserialize<'b>,
{
T::deserialize(self)
}
pub fn deserialize_into<T>(self) -> Result<T, Error>
where
T: Deserialize<'a>,
{
T::deserialize(self)
}
}
convert!(enum Value<'a>, variant Value::Bool: type bool);
convert!(enum Value<'a>, variant Value::I64: type i64);
convert!(enum Value<'a>, variant Value::F64: type f64);
convert!(enum Value<'a>, variant Value::Bytes: type Box<Cow<'a, [u8]>>);
convert!(enum Value<'a>, variant Value::String: type Box<Cow<'a, str>>);
convert!(enum Value<'a>, variant Value::List: type Box<Cow<'a, List<'a>>>);
convert!(enum Value<'a>, variant Value::Table: type Box<Cow<'a, Table<'a>>>);
convert!(enum Value<'a>, type i64: from i8, i16, i32, u8, u16, u32);
convert!(enum Value<'a>, type i64: from_as u64, isize, usize);
convert!(enum Value<'a>, type f64: from f32);
convert!(enum Value<'a>, type Box<Cow<'a, [u8]>>: from Cow<'a, [u8]>);
convert!(enum Value<'a>, type Box<Cow<'a, [u8]>>: ref Cow<'a, [u8]>);
convert!(enum Value<'a>, type Box<Cow<'a, str>>: from Cow<'a, str>);
convert!(enum Value<'a>, type Box<Cow<'a, str>>: ref Cow<'a, str>);
convert!(enum Value<'a>, type Box<Cow<'a, List<'a>>>: from Cow<'a, List<'a>>);
convert!(enum Value<'a>, type Box<Cow<'a, List<'a>>>: ref Cow<'a, List<'a>>);
convert!(enum Value<'a>, type Box<Cow<'a, Table<'a>>>: from Cow<'a, Table<'a>>);
convert!(enum Value<'a>, type Box<Cow<'a, Table<'a>>>: ref Cow<'a, Table<'a>>);
convert!(enum Value<'a>: cow [u8], Vec<u8>);
convert!(enum Value<'a>: cow str, String);
convert!(enum Value<'a>: cow List<'a>, List<'a>);
convert!(enum Value<'a>: cow Table<'a>, Table<'a>);
impl<'a> Default for Value<'a> {
fn default() -> Self {
Value::Null
}
}
impl<'a> AsRef<Value<'a>> for Value<'a> {
fn as_ref(&self) -> &Value<'a> {
self
}
}
impl<'a> AsMut<Value<'a>> for Value<'a> {
fn as_mut(&mut self) -> &mut Value<'a> {
self
}
}
impl<'a> PartialOrd for Value<'a> {
fn partial_cmp(&self, other: &Value<'a>) -> Option<cmp::Ordering> {
use Value::*;
match (self, other) {
(Null, Null) => Some(cmp::Ordering::Equal),
(Bool(x), Bool(y)) => x.partial_cmp(y),
(I64(x), I64(y)) => x.partial_cmp(y),
(F64(x), F64(y)) => x.partial_cmp(y),
(Bytes(x), Bytes(y)) => x.partial_cmp(y),
(String(x), String(y)) => x.partial_cmp(y),
_ => None,
}
}
}