mod serde;
pub use self::serde::{to_value, from_value};
use table::Table;
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
Null,
Boolean(bool),
Integer(i64),
Number(f64),
Text(String),
List(Vec<Value>),
Table(Table),
}
pub trait FromValue<'a>: Sized {
fn from_value(value: &'a Value) -> Option<Self>;
}
pub trait FromValueMut<'a>: Sized {
fn from_value_mut(value: &'a mut Value) -> Option<Self>;
}
impl <'a, T> FromValue<'a> for T
where
T: From<&'a Value>,
{
fn from_value(value: &'a Value) -> Option<T> {
Some(T::from(value))
}
}
impl<'a, T> FromValueMut<'a> for T
where
T: FromValue<'a>,
{
fn from_value_mut(value: &'a mut Value) -> Option<T> {
T::from_value(value)
}
}
impl From<bool> for Value {
fn from(x: bool) -> Value {
Value::Boolean(x)
}
}
impl<'a> FromValue<'a> for bool {
fn from_value(value: &'a Value) -> Option<bool> {
match value {
Value::Boolean(x) => Some(*x),
Value::Integer(x) => Some(*x != 0),
Value::Text(x) => x.parse().ok(),
_ => None,
}
}
}
impl From<i64> for Value {
fn from(x: i64) -> Value {
Value::Integer(x)
}
}
impl<'a> FromValue<'a> for i64 {
fn from_value(value: &'a Value) -> Option<i64> {
match value {
Value::Integer(x) => Some(*x),
Value::Number(x) => Some(*x as i64),
Value::Text(x) => x.parse().ok(),
_ => None,
}
}
}
impl From<f64> for Value {
fn from(x: f64) -> Value {
Value::Number(x)
}
}
impl<'a> FromValue<'a> for f64 {
fn from_value(value: &'a Value) -> Option<f64> {
match value {
Value::Integer(x) => Some(*x as f64),
Value::Number(x) => Some(*x),
Value::Text(x) => x.parse().ok(),
_ => None,
}
}
}
impl From<String> for Value {
fn from(x: String) -> Value {
Value::Text(x)
}
}
impl<'a> FromValue<'a> for &'a String {
fn from_value(value: &'a Value) -> Option<&'a String> {
match value {
Value::Text(x) => Some(x),
_ => None,
}
}
}
impl<'a> FromValueMut<'a> for &'a mut String {
fn from_value_mut(value: &'a mut Value) -> Option<&'a mut String> {
match value {
Value::Text(x) => Some(x),
_ => None,
}
}
}
impl<'a> FromValue<'a> for String {
fn from_value(value: &'a Value) -> Option<String> {
match value {
Value::Boolean(x) => Some(x.to_string()),
Value::Integer(x) => Some(x.to_string()),
Value::Number(x) => Some(x.to_string()),
Value::Text(x) => Some(x.to_string()),
_ => None,
}
}
}
impl From<Vec<Value>> for Value {
fn from(x: Vec<Value>) -> Value {
Value::List(x)
}
}
impl<'a> FromValue<'a> for &'a Vec<Value> {
fn from_value(value: &'a Value) -> Option<&'a Vec<Value>> {
match value {
Value::List(x) => Some(x),
_ => None,
}
}
}
impl<'a> FromValueMut<'a> for &'a mut Vec<Value> {
fn from_value_mut(value: &'a mut Value) -> Option<&'a mut Vec<Value>> {
match value {
Value::List(x) => Some(x),
_ => None,
}
}
}
impl From<Table> for Value {
fn from(x: Table) -> Value {
Value::Table(x)
}
}
impl<'a> FromValue<'a> for &'a Table {
fn from_value(value: &'a Value) -> Option<&'a Table> {
match value {
Value::Table(x) => Some(x),
_ => None,
}
}
}
impl<'a> FromValueMut<'a> for &'a mut Table {
fn from_value_mut(value: &'a mut Value) -> Option<&'a mut Table> {
match value {
Value::Table(x) => Some(x),
_ => None,
}
}
}
impl<T> From<Option<T>> for Value
where
Value: From<T>,
{
fn from(x: Option<T>) -> Value {
match x {
None => Value::Null,
Some(t) => Value::from(t),
}
}
}
macro_rules! derive_value {
($x:ty as $($y:ty),*) => {$(
impl From<$y> for Value {
fn from(y: $y) -> Value {
Value::from(y as $x)
}
}
impl<'a> FromValue<'a> for $y {
fn from_value(value: &'a Value) -> Option<$y> {
<$x>::from_value(value)
.map(|x| x as $y)
}
}
)*}
}
derive_value!(i64 as i8, i16, i32, isize, u8, u16, u32, u64, usize);
derive_value!(f64 as f32);