use std::convert::From;
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Integer {
U64(u64),
I64(i64),
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Float {
F32(f32),
F64(f64),
}
#[derive(Clone, Debug, PartialEq)]
pub enum Value {
Nil,
Boolean(bool),
Integer(Integer),
Float(Float),
String(String),
Binary(Vec<u8>),
Array(Vec<Value>),
Map(Vec<(Value, Value)>),
Ext(i8, Vec<u8>),
}
impl From<bool> for Value {
fn from(v: bool) -> Value {
Value::Boolean(v)
}
}
impl From<u8> for Value {
fn from(v: u8) -> Value {
Value::Integer(Integer::U64(From::from(v)))
}
}
impl From<u16> for Value {
fn from(v: u16) -> Value {
Value::Integer(Integer::U64(From::from(v)))
}
}
impl From<u32> for Value {
fn from(v: u32) -> Value {
Value::Integer(Integer::U64(From::from(v)))
}
}
impl From<u64> for Value {
fn from(v: u64) -> Value {
Value::Integer(Integer::U64(From::from(v)))
}
}
impl From<usize> for Value {
fn from(v: usize) -> Value {
Value::Integer(Integer::U64(v as u64))
}
}
impl From<i8> for Value {
fn from(v: i8) -> Value {
Value::Integer(Integer::I64(From::from(v)))
}
}
impl From<i16> for Value {
fn from(v: i16) -> Value {
Value::Integer(Integer::I64(From::from(v)))
}
}
impl From<i32> for Value {
fn from(v: i32) -> Value {
Value::Integer(Integer::I64(From::from(v)))
}
}
impl From<i64> for Value {
fn from(v: i64) -> Value {
Value::Integer(Integer::I64(From::from(v)))
}
}
impl From<isize> for Value {
fn from(v: isize) -> Value {
Value::Integer(Integer::I64(v as i64))
}
}
impl From<f32> for Value {
fn from(v: f32) -> Value {
Value::Float(Float::F32(v))
}
}
impl From<f64> for Value {
fn from(v: f64) -> Value {
Value::Float(Float::F64(v))
}
}
impl ::std::fmt::Display for Value {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
match *self {
Value::Nil => write!(f, "nil"),
Value::Boolean(val) => write!(f, "{}", val),
Value::Integer(Integer::U64(val)) => write!(f, "{}", val),
Value::Integer(Integer::I64(val)) => write!(f, "{}", val),
Value::Float(Float::F32(val)) => write!(f, "{}", val),
Value::Float(Float::F64(val)) => write!(f, "{}", val),
Value::String(ref val) => write!(f, "\"{}\"", val),
Value::Binary(ref val) => write!(f, "{:?}", val),
Value::Array(ref vec) => {
let res = vec.iter()
.map(|val| format!("{}", val))
.collect::<Vec<String>>()
.join(", ");
write!(f, "[{}]", res)
}
Value::Map(ref vec) => {
try!(write!(f, "{{"));
match vec.iter().take(1).next() {
Some(&(ref k, ref v)) => {
try!(write!(f, "{}: {}", k, v));
}
None => {
try!(write!(f, ""));
}
}
for &(ref k, ref v) in vec.iter().skip(1) {
try!(write!(f, ", {}: {}", k, v));
}
write!(f, "}}")
}
Value::Ext(ty, ref data) => {
write!(f, "[{}, {:?}]", ty, data)
}
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum ValueRef<'a> {
Nil,
Boolean(bool),
Integer(Integer),
Float(Float),
String(&'a str),
Binary(&'a [u8]),
Array(Vec<ValueRef<'a>>),
Map(Vec<(ValueRef<'a>, ValueRef<'a>)>),
Ext(i8, &'a [u8]),
}
impl<'a> ValueRef<'a> {
pub fn to_owned(&self) -> Value {
match self {
&ValueRef::Nil => Value::Nil,
&ValueRef::Boolean(val) => Value::Boolean(val),
&ValueRef::Integer(val) => Value::Integer(val),
&ValueRef::Float(val) => Value::Float(val),
&ValueRef::String(val) => Value::String(val.to_owned()),
&ValueRef::Binary(val) => Value::Binary(val.to_vec()),
&ValueRef::Array(ref val) => {
Value::Array(val.iter().map(|v| v.to_owned()).collect())
}
&ValueRef::Map(ref val) => {
Value::Map(val.iter().map(|&(ref k, ref v)| (k.to_owned(), v.to_owned())).collect())
}
&ValueRef::Ext(ty, buf) => Value::Ext(ty, buf.to_vec()),
}
}
}