#[cfg(feature = "with-serde")]
#[macro_use]
extern crate serde;
extern crate rmp;
extern crate num_traits;
use std::borrow::Cow;
use std::fmt::{self, Debug, Display};
use std::ops::Index;
use std::str::Utf8Error;
use num_traits::NumCast;
pub mod decode;
pub mod encode;
#[cfg(feature = "with-serde")]
pub mod ext;
#[derive(Copy, Clone, Debug, PartialEq)]
enum IntPriv {
PosInt(u64),
NegInt(i64),
}
#[derive(Copy, Clone, PartialEq)]
pub struct Integer {
n: IntPriv,
}
impl Integer {
#[inline]
pub fn is_i64(&self) -> bool {
match self.n {
IntPriv::PosInt(n) => n <= std::i64::MAX as u64,
IntPriv::NegInt(..) => true,
}
}
#[inline]
pub fn is_u64(&self) -> bool {
match self.n {
IntPriv::PosInt(..) => true,
IntPriv::NegInt(..) => false,
}
}
#[inline]
pub fn as_i64(&self) -> Option<i64> {
match self.n {
IntPriv::PosInt(n) => NumCast::from(n),
IntPriv::NegInt(n) => Some(n),
}
}
#[inline]
pub fn as_u64(&self) -> Option<u64> {
match self.n {
IntPriv::PosInt(n) => Some(n),
IntPriv::NegInt(n) => NumCast::from(n),
}
}
#[inline]
pub fn as_f64(&self) -> Option<f64> {
match self.n {
IntPriv::PosInt(n) => NumCast::from(n),
IntPriv::NegInt(n) => NumCast::from(n),
}
}
}
impl Debug for Integer {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
Debug::fmt(&self.n, fmt)
}
}
impl Display for Integer {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self.n {
IntPriv::PosInt(v) => Display::fmt(&v, fmt),
IntPriv::NegInt(v) => Display::fmt(&v, fmt),
}
}
}
impl From<u8> for Integer {
fn from(n: u8) -> Self {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
impl From<u16> for Integer {
fn from(n: u16) -> Self {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
impl From<u32> for Integer {
fn from(n: u32) -> Self {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
impl From<u64> for Integer {
fn from(n: u64) -> Self {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
impl From<usize> for Integer {
fn from(n: usize) -> Self {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
impl From<i8> for Integer {
fn from(n: i8) -> Self {
if n < 0 {
Integer { n: IntPriv::NegInt(n as i64) }
} else {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
}
impl From<i16> for Integer {
fn from(n: i16) -> Self {
if n < 0 {
Integer { n: IntPriv::NegInt(n as i64) }
} else {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
}
impl From<i32> for Integer {
fn from(n: i32) -> Self {
if n < 0 {
Integer { n: IntPriv::NegInt(n as i64) }
} else {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
}
impl From<i64> for Integer {
fn from(n: i64) -> Self {
if n < 0 {
Integer { n: IntPriv::NegInt(n as i64) }
} else {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
}
impl From<isize> for Integer {
fn from(n: isize) -> Self {
if n < 0 {
Integer { n: IntPriv::NegInt(n as i64) }
} else {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Utf8String {
s: Result<String, (Vec<u8>, Utf8Error)>,
}
impl Utf8String {
pub fn is_str(&self) -> bool {
self.s.is_ok()
}
pub fn is_err(&self) -> bool {
self.s.is_err()
}
pub fn as_str(&self) -> Option<&str> {
match self.s {
Ok(ref s) => Some(s.as_str()),
Err(..) => None,
}
}
pub fn as_err(&self) -> Option<&Utf8Error> {
match self.s {
Ok(..) => None,
Err((.., ref err)) => Some(&err),
}
}
pub fn as_bytes(&self) -> &[u8] {
match self.s {
Ok(ref s) => s.as_bytes(),
Err(ref err) => &err.0[..],
}
}
pub fn into_str(self) -> Option<String> {
self.s.ok()
}
pub fn into_bytes(self) -> Vec<u8> {
match self.s {
Ok(s) => s.into_bytes(),
Err(err) => err.0,
}
}
}
impl Display for Utf8String {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self.s {
Ok(ref s) => write!(fmt, "\"{}\"", s),
Err(ref err) => Debug::fmt(&err.0, fmt),
}
}
}
impl<'a> From<String> for Utf8String {
fn from(val: String) -> Self {
Utf8String {
s: Ok(val),
}
}
}
impl<'a> From<&'a str> for Utf8String {
fn from(val: &str) -> Self {
Utf8String {
s: Ok(val.into()),
}
}
}
impl<'a> From<Cow<'a, str>> for Utf8String {
fn from(val: Cow<'a, str>) -> Self {
Utf8String {
s: Ok(val.into()),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Utf8StringRef<'a> {
s: Result<&'a str, (&'a [u8], Utf8Error)>,
}
impl<'a> Utf8StringRef<'a> {
pub fn is_str(&self) -> bool {
self.s.is_ok()
}
pub fn is_err(&self) -> bool {
self.s.is_err()
}
pub fn as_str(&self) -> Option<&str> {
match self.s {
Ok(ref s) => Some(s),
Err(..) => None,
}
}
pub fn as_err(&self) -> Option<&Utf8Error> {
match self.s {
Ok(..) => None,
Err((.., ref err)) => Some(&err),
}
}
pub fn as_bytes(&self) -> &[u8] {
match self.s {
Ok(ref s) => s.as_bytes(),
Err(ref err) => err.0,
}
}
pub fn into_str(self) -> Option<String> {
self.s.ok().map(|s| s.into())
}
pub fn into_bytes(self) -> Vec<u8> {
match self.s {
Ok(s) => s.as_bytes().into(),
Err(err) => err.0.into(),
}
}
}
impl<'a> Display for Utf8StringRef<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self.s {
Ok(ref s) => write!(fmt, "\"{}\"", s),
Err(ref err) => Debug::fmt(&err.0, fmt),
}
}
}
impl<'a> From<&'a str> for Utf8StringRef<'a> {
fn from(val: &'a str) -> Self {
Utf8StringRef {
s: Ok(val),
}
}
}
impl<'a> Into<Utf8String> for Utf8StringRef<'a> {
fn into(self) -> Utf8String {
match self.s {
Ok(s) => Utf8String { s: Ok(s.into()) },
Err((buf, err)) => Utf8String { s: Err((buf.into(), err)) }
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum Value {
Nil,
Boolean(bool),
Integer(Integer),
F32(f32),
F64(f64),
String(Utf8String),
Binary(Vec<u8>),
Array(Vec<Value>),
Map(Vec<(Value, Value)>),
Ext(i8, Vec<u8>),
}
impl Value {
pub fn is_nil(&self) -> bool {
if let Value::Nil = *self {
true
} else {
false
}
}
pub fn is_bool(&self) -> bool {
self.as_bool().is_some()
}
pub fn is_i64(&self) -> bool {
if let Value::Integer(ref v) = *self {
v.is_i64()
} else {
false
}
}
pub fn is_u64(&self) -> bool {
if let Value::Integer(ref v) = *self {
v.is_u64()
} else {
false
}
}
pub fn is_f32(&self) -> bool {
if let Value::F32(..) = *self {
true
} else {
false
}
}
pub fn is_f64(&self) -> bool {
if let Value::F64(..) = *self {
true
} else {
false
}
}
pub fn is_number(&self) -> bool {
match *self {
Value::Integer(..) | Value::F32(..) | Value::F64(..) => true,
_ => false,
}
}
pub fn is_str(&self) -> bool {
self.as_str().is_some()
}
pub fn is_bin(&self) -> bool {
self.as_slice().is_some()
}
pub fn is_array(&self) -> bool {
self.as_array().is_some()
}
pub fn is_map(&self) -> bool {
self.as_map().is_some()
}
pub fn is_ext(&self) -> bool {
self.as_ext().is_some()
}
pub fn as_bool(&self) -> Option<bool> {
if let Value::Boolean(val) = *self {
Some(val)
} else {
None
}
}
pub fn as_i64(&self) -> Option<i64> {
match *self {
Value::Integer(ref n) => n.as_i64(),
_ => None,
}
}
pub fn as_u64(&self) -> Option<u64> {
match *self {
Value::Integer(ref n) => n.as_u64(),
_ => None,
}
}
pub fn as_f64(&self) -> Option<f64> {
match *self {
Value::Integer(ref n) => n.as_f64(),
Value::F32(n) => Some(From::from(n)),
Value::F64(n) => Some(n),
_ => None,
}
}
pub fn as_str(&self) -> Option<&str> {
if let Value::String(ref val) = *self {
val.as_str()
} else {
None
}
}
pub fn as_slice(&self) -> Option<&[u8]> {
if let Value::Binary(ref val) = *self {
Some(val)
} else if let Value::String(ref val) = *self {
Some(val.as_bytes())
} else {
None
}
}
pub fn as_array(&self) -> Option<&Vec<Value>> {
if let Value::Array(ref array) = *self {
Some(&*array)
} else {
None
}
}
pub fn as_map(&self) -> Option<&Vec<(Value, Value)>> {
if let Value::Map(ref map) = *self {
Some(map)
} else {
None
}
}
pub fn as_ext(&self) -> Option<(i8, &[u8])> {
if let Value::Ext(ty, ref buf) = *self {
Some((ty, buf))
} else {
None
}
}
}
static NIL: Value = Value::Nil;
static NIL_REF: ValueRef<'static> = ValueRef::Nil;
impl Index<usize> for Value {
type Output = Value;
fn index(&self, index: usize) -> &Value {
self.as_array().and_then(|v| v.get(index)).unwrap_or(&NIL)
}
}
impl From<bool> for Value {
fn from(v: bool) -> Self {
Value::Boolean(v)
}
}
impl From<u8> for Value {
fn from(v: u8) -> Self {
Value::Integer(From::from(v))
}
}
impl From<u16> for Value {
fn from(v: u16) -> Self {
Value::Integer(From::from(v))
}
}
impl From<u32> for Value {
fn from(v: u32) -> Self {
Value::Integer(From::from(v))
}
}
impl From<u64> for Value {
fn from(v: u64) -> Self {
Value::Integer(From::from(v))
}
}
impl From<usize> for Value {
fn from(v: usize) -> Self {
Value::Integer(From::from(v))
}
}
impl From<i8> for Value {
fn from(v: i8) -> Self {
Value::Integer(From::from(v))
}
}
impl From<i16> for Value {
fn from(v: i16) -> Self {
Value::Integer(From::from(v))
}
}
impl From<i32> for Value {
fn from(v: i32) -> Self {
Value::Integer(From::from(v))
}
}
impl From<i64> for Value {
fn from(v: i64) -> Self {
Value::Integer(From::from(v))
}
}
impl From<isize> for Value {
fn from(v: isize) -> Self {
Value::Integer(From::from(v))
}
}
impl From<f32> for Value {
fn from(v: f32) -> Self {
Value::F32(v)
}
}
impl From<f64> for Value {
fn from(v: f64) -> Self {
Value::F64(v)
}
}
impl From<String> for Value {
fn from(v: String) -> Self {
Value::String(Utf8String::from(v))
}
}
impl<'a> From<&'a str> for Value {
fn from(v: &str) -> Self {
Value::String(Utf8String::from(v))
}
}
impl<'a> From<Cow<'a, str>> for Value {
fn from(v: Cow<'a, str>) -> Self {
Value::String(Utf8String::from(v))
}
}
impl From<Vec<u8>> for Value {
fn from(v: Vec<u8>) -> Self {
Value::Binary(v)
}
}
impl<'a> From<&'a [u8]> for Value {
fn from(v: &[u8]) -> Self {
Value::Binary(v.into())
}
}
impl<'a> From<Cow<'a, [u8]>> for Value {
fn from(v: Cow<'a, [u8]>) -> Self {
Value::Binary(v.into())
}
}
impl From<Vec<Value>> for Value {
fn from(v: Vec<Value>) -> Self {
Value::Array(v)
}
}
impl From<Vec<(Value, Value)>> for Value {
fn from(v: Vec<(Value, Value)>) -> Self {
Value::Map(v)
}
}
impl Display for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
Value::Nil => Display::fmt("nil", f),
Value::Boolean(val) => write!(f, "{}", val),
Value::Integer(ref val) => write!(f, "{}", val),
Value::F32(val) => write!(f, "{}", val),
Value::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),
F32(f32),
F64(f64),
String(Utf8StringRef<'a>),
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::F32(val) => Value::F32(val),
&ValueRef::F64(val) => Value::F64(val),
&ValueRef::String(val) => Value::String(val.into()),
&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()),
}
}
pub fn index(&self, index: usize) -> &ValueRef {
self.as_array().and_then(|v| v.get(index)).unwrap_or(&NIL_REF)
}
pub fn as_u64(&self) -> Option<u64> {
match *self {
ValueRef::Integer(ref n) => n.as_u64(),
_ => None,
}
}
pub fn as_array(&self) -> Option<&Vec<ValueRef>> {
if let ValueRef::Array(ref array) = *self {
Some(&*array)
} else {
None
}
}
pub fn into_array(self) -> Option<Vec<ValueRef<'a>>> {
if let ValueRef::Array(array) = self {
Some(array)
} else {
None
}
}
}
impl<'a> From<u8> for ValueRef<'a> {
fn from(v: u8) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<u16> for ValueRef<'a> {
fn from(v: u16) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<u32> for ValueRef<'a> {
fn from(v: u32) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<u64> for ValueRef<'a> {
fn from(v: u64) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<usize> for ValueRef<'a> {
fn from(v: usize) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<i8> for ValueRef<'a> {
fn from(v: i8) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<i16> for ValueRef<'a> {
fn from(v: i16) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<i32> for ValueRef<'a> {
fn from(v: i32) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<i64> for ValueRef<'a> {
fn from(v: i64) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<isize> for ValueRef<'a> {
fn from(v: isize) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<f32> for ValueRef<'a> {
fn from(v: f32) -> Self {
ValueRef::F32(v)
}
}
impl<'a> From<f64> for ValueRef<'a> {
fn from(v: f64) -> Self {
ValueRef::F64(v)
}
}
impl<'a> From<&'a str> for ValueRef<'a> {
fn from(v: &'a str) -> Self {
ValueRef::String(Utf8StringRef::from(v))
}
}
impl<'a> From<&'a [u8]> for ValueRef<'a> {
fn from(v: &'a [u8]) -> Self {
ValueRef::Binary(v.into())
}
}
impl<'a> From<Vec<ValueRef<'a>>> for ValueRef<'a> {
fn from(v: Vec<ValueRef<'a>>) -> Self {
ValueRef::Array(v)
}
}
impl<'a> From<Vec<(ValueRef<'a>, ValueRef<'a>)>> for ValueRef<'a> {
fn from(v: Vec<(ValueRef<'a>, ValueRef<'a>)>) -> Self {
ValueRef::Map(v)
}
}
impl<'a> Display for ValueRef<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
ValueRef::Nil => write!(f, "nil"),
ValueRef::Boolean(val) => write!(f, "{}", val),
ValueRef::Integer(ref val) => write!(f, "{}", val),
ValueRef::F32(val) => write!(f, "{}", val),
ValueRef::F64(val) => write!(f, "{}", val),
ValueRef::String(ref val) => write!(f, "\"{}\"", val),
ValueRef::Binary(ref val) => write!(f, "{:?}", val),
ValueRef::Array(ref vec) => {
let res = vec.iter()
.map(|val| format!("{}", val))
.collect::<Vec<String>>()
.join(", ");
write!(f, "[{}]", res)
}
ValueRef::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, "}}")
}
ValueRef::Ext(ty, ref data) => {
write!(f, "[{}, {:?}]", ty, data)
}
}
}
}