#![forbid(unsafe_code)]
use std::borrow::Cow;
use std::convert::TryFrom;
use std::fmt::{self, Debug, Display};
use std::iter::FromIterator;
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),
}
pub const MSGPACK_EXT_STRUCT_NAME: &str = "_ExtStruct";
#[derive(Copy, Clone, PartialEq)]
pub struct Integer {
n: IntPriv,
}
impl Integer {
#[inline]
#[must_use]
pub fn is_i64(&self) -> bool {
match self.n {
IntPriv::PosInt(n) => n <= std::i64::MAX as u64,
IntPriv::NegInt(..) => true,
}
}
#[inline]
#[must_use]
pub fn is_u64(&self) -> bool {
match self.n {
IntPriv::PosInt(..) => true,
IntPriv::NegInt(..) => false,
}
}
#[inline]
#[must_use]
pub fn as_i64(&self) -> Option<i64> {
match self.n {
IntPriv::PosInt(n) => NumCast::from(n),
IntPriv::NegInt(n) => Some(n),
}
}
#[inline]
#[must_use]
pub fn as_u64(&self) -> Option<u64> {
match self.n {
IntPriv::PosInt(n) => Some(n),
IntPriv::NegInt(n) => NumCast::from(n),
}
}
#[inline]
#[must_use]
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 {
#[inline]
fn from(n: u8) -> Self {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
impl From<u16> for Integer {
#[inline]
fn from(n: u16) -> Self {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
impl From<u32> for Integer {
#[inline]
fn from(n: u32) -> Self {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
impl From<u64> for Integer {
#[inline]
fn from(n: u64) -> Self {
Integer { n: IntPriv::PosInt(n) }
}
}
impl From<usize> for Integer {
#[inline]
fn from(n: usize) -> Self {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
impl From<i8> for Integer {
#[inline]
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 {
#[inline]
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 {
#[inline]
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 {
#[inline]
fn from(n: i64) -> Self {
if n < 0 {
Integer { n: IntPriv::NegInt(n) }
} else {
Integer { n: IntPriv::PosInt(n as u64) }
}
}
}
impl From<isize> for Integer {
#[inline]
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 {
#[inline]
#[must_use]
pub fn is_str(&self) -> bool {
self.s.is_ok()
}
#[inline]
#[must_use]
pub fn is_err(&self) -> bool {
self.s.is_err()
}
#[inline]
#[must_use]
pub fn as_str(&self) -> Option<&str> {
match self.s {
Ok(ref s) => Some(s.as_str()),
Err(..) => None,
}
}
#[inline]
#[must_use]
pub fn as_err(&self) -> Option<&Utf8Error> {
match self.s {
Ok(..) => None,
Err((_, ref err)) => Some(err),
}
}
#[inline]
#[must_use]
pub fn as_bytes(&self) -> &[u8] {
match self.s {
Ok(ref s) => s.as_bytes(),
Err(ref err) => &err.0[..],
}
}
#[inline]
#[must_use]
pub fn into_str(self) -> Option<String> {
self.s.ok()
}
#[inline]
#[must_use]
pub fn into_bytes(self) -> Vec<u8> {
match self.s {
Ok(s) => s.into_bytes(),
Err(err) => err.0,
}
}
#[inline]
#[must_use]
pub fn as_ref(&self) -> Utf8StringRef<'_> {
match self.s {
Ok(ref s) => Utf8StringRef { s: Ok(s.as_str()) },
Err((ref buf, err)) => Utf8StringRef { s: Err((&buf[..], err)) },
}
}
}
impl Display for Utf8String {
#[cold]
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self.s {
Ok(ref s) => Debug::fmt(&s, fmt),
Err(ref err) => Debug::fmt(&err.0, fmt),
}
}
}
impl<'a> From<String> for Utf8String {
#[inline]
fn from(val: String) -> Self {
Utf8String { s: Ok(val) }
}
}
impl<'a> From<&'a str> for Utf8String {
#[inline]
fn from(val: &str) -> Self {
Utf8String { s: Ok(val.into()) }
}
}
impl<'a> From<Cow<'a, str>> for Utf8String {
#[inline]
fn from(val: Cow<'a, str>) -> Self {
Utf8String {
s: Ok(val.into_owned()),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Utf8StringRef<'a> {
s: Result<&'a str, (&'a [u8], Utf8Error)>,
}
impl<'a> Utf8StringRef<'a> {
#[inline]
#[must_use]
pub fn is_str(&self) -> bool {
self.s.is_ok()
}
#[inline]
#[must_use]
pub fn is_err(&self) -> bool {
self.s.is_err()
}
#[inline]
#[must_use]
pub fn as_str(&self) -> Option<&str> {
match self.s {
Ok(s) => Some(s),
Err(..) => None,
}
}
#[inline]
#[must_use]
pub fn as_err(&self) -> Option<&Utf8Error> {
match self.s {
Ok(..) => None,
Err((_, ref err)) => Some(err),
}
}
#[inline]
#[must_use]
pub fn as_bytes(&self) -> &[u8] {
match self.s {
Ok(s) => s.as_bytes(),
Err(ref err) => err.0,
}
}
#[inline]
#[must_use]
pub fn into_string(self) -> Option<String> {
self.s.ok().map(|s| s.into())
}
#[inline]
#[must_use]
pub fn into_str(self) -> Option<&'a str> {
self.s.ok()
}
#[inline]
#[must_use]
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> {
#[cold]
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self.s {
Ok(ref s) => Debug::fmt(&s, fmt),
Err(ref err) => Debug::fmt(&err.0, fmt),
}
}
}
impl<'a> From<&'a str> for Utf8StringRef<'a> {
#[inline]
fn from(val: &'a str) -> Self {
Utf8StringRef { s: Ok(val) }
}
}
impl<'a> From<Utf8StringRef<'a>> for Utf8String {
fn from(val: Utf8StringRef<'a>) -> Self {
match val.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 {
#[must_use]
pub fn as_ref(&self) -> ValueRef<'_> {
match *self {
Value::Nil => ValueRef::Nil,
Value::Boolean(val) => ValueRef::Boolean(val),
Value::Integer(val) => ValueRef::Integer(val),
Value::F32(val) => ValueRef::F32(val),
Value::F64(val) => ValueRef::F64(val),
Value::String(ref val) => ValueRef::String(val.as_ref()),
Value::Binary(ref val) => ValueRef::Binary(val.as_slice()),
Value::Array(ref val) => {
ValueRef::Array(val.iter().map(|v| v.as_ref()).collect())
}
Value::Map(ref val) => {
ValueRef::Map(val.iter().map(|(k, v)| (k.as_ref(), v.as_ref())).collect())
}
Value::Ext(ty, ref buf) => ValueRef::Ext(ty, buf.as_slice()),
}
}
#[inline]
#[must_use]
pub fn is_nil(&self) -> bool {
if let Value::Nil = *self {
true
} else {
false
}
}
#[inline]
#[must_use]
pub fn is_bool(&self) -> bool {
self.as_bool().is_some()
}
#[inline]
#[must_use]
pub fn is_i64(&self) -> bool {
if let Value::Integer(ref v) = *self {
v.is_i64()
} else {
false
}
}
#[inline]
#[must_use]
pub fn is_u64(&self) -> bool {
if let Value::Integer(ref v) = *self {
v.is_u64()
} else {
false
}
}
#[inline]
#[must_use]
pub fn is_f32(&self) -> bool {
if let Value::F32(..) = *self {
true
} else {
false
}
}
#[inline]
#[must_use]
pub fn is_f64(&self) -> bool {
if let Value::F64(..) = *self {
true
} else {
false
}
}
#[must_use]
pub fn is_number(&self) -> bool {
match *self {
Value::Integer(..) | Value::F32(..) | Value::F64(..) => true,
_ => false,
}
}
#[inline]
#[must_use]
pub fn is_str(&self) -> bool {
self.as_str().is_some()
}
#[inline]
#[must_use]
pub fn is_bin(&self) -> bool {
self.as_slice().is_some()
}
#[inline]
#[must_use]
pub fn is_array(&self) -> bool {
self.as_array().is_some()
}
#[inline]
#[must_use]
pub fn is_map(&self) -> bool {
self.as_map().is_some()
}
#[inline]
#[must_use]
pub fn is_ext(&self) -> bool {
self.as_ext().is_some()
}
#[inline]
#[must_use]
pub fn as_bool(&self) -> Option<bool> {
if let Value::Boolean(val) = *self {
Some(val)
} else {
None
}
}
#[inline]
#[must_use]
pub fn as_i64(&self) -> Option<i64> {
match *self {
Value::Integer(ref n) => n.as_i64(),
_ => None,
}
}
#[inline]
#[must_use]
pub fn as_u64(&self) -> Option<u64> {
match *self {
Value::Integer(ref n) => n.as_u64(),
_ => None,
}
}
#[must_use]
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,
}
}
#[inline]
#[must_use]
pub fn as_str(&self) -> Option<&str> {
if let Value::String(ref val) = *self {
val.as_str()
} else {
None
}
}
#[must_use]
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
}
}
#[inline]
#[must_use]
pub fn as_array(&self) -> Option<&Vec<Value>> {
if let Value::Array(ref array) = *self {
Some(array)
} else {
None
}
}
#[inline]
#[must_use]
pub fn as_map(&self) -> Option<&Vec<(Value, Value)>> {
if let Value::Map(ref map) = *self {
Some(map)
} else {
None
}
}
#[inline]
#[must_use]
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 Index<&str> for Value {
type Output = Value;
fn index(&self, index: &str) -> &Value {
if let Value::Map(ref map) = *self {
if let Some(found) = map.iter().find(
|(key, _val)| {
if let Value::String(ref strval) = *key {
if let Some(s) = strval.as_str() {
if s == index { return true; }
}
}
false
})
{
return &found.1;
}
}
&NIL
}
}
impl From<bool> for Value {
#[inline]
fn from(v: bool) -> Self {
Value::Boolean(v)
}
}
impl From<u8> for Value {
#[inline]
fn from(v: u8) -> Self {
Value::Integer(From::from(v))
}
}
impl From<u16> for Value {
#[inline]
fn from(v: u16) -> Self {
Value::Integer(From::from(v))
}
}
impl From<u32> for Value {
#[inline]
fn from(v: u32) -> Self {
Value::Integer(From::from(v))
}
}
impl From<u64> for Value {
#[inline]
fn from(v: u64) -> Self {
Value::Integer(From::from(v))
}
}
impl From<usize> for Value {
#[inline]
fn from(v: usize) -> Self {
Value::Integer(From::from(v))
}
}
impl From<i8> for Value {
#[inline]
fn from(v: i8) -> Self {
Value::Integer(From::from(v))
}
}
impl From<i16> for Value {
#[inline]
fn from(v: i16) -> Self {
Value::Integer(From::from(v))
}
}
impl From<i32> for Value {
#[inline]
fn from(v: i32) -> Self {
Value::Integer(From::from(v))
}
}
impl From<i64> for Value {
#[inline]
fn from(v: i64) -> Self {
Value::Integer(From::from(v))
}
}
impl From<isize> for Value {
#[inline]
fn from(v: isize) -> Self {
Value::Integer(From::from(v))
}
}
impl From<f32> for Value {
#[inline]
fn from(v: f32) -> Self {
Value::F32(v)
}
}
impl From<f64> for Value {
#[inline]
fn from(v: f64) -> Self {
Value::F64(v)
}
}
impl From<String> for Value {
#[inline]
fn from(v: String) -> Self {
Value::String(Utf8String::from(v))
}
}
impl<'a> From<&'a str> for Value {
#[inline]
fn from(v: &str) -> Self {
Value::String(Utf8String::from(v))
}
}
impl<'a> From<Cow<'a, str>> for Value {
#[inline]
fn from(v: Cow<'a, str>) -> Self {
Value::String(Utf8String::from(v))
}
}
impl From<Vec<u8>> for Value {
#[inline]
fn from(v: Vec<u8>) -> Self {
Value::Binary(v)
}
}
impl<'a> From<&'a [u8]> for Value {
#[inline]
fn from(v: &[u8]) -> Self {
Value::Binary(v.into())
}
}
impl<'a> From<Cow<'a, [u8]>> for Value {
#[inline]
fn from(v: Cow<'a, [u8]>) -> Self {
Value::Binary(v.into_owned())
}
}
impl From<Vec<Value>> for Value {
#[inline]
fn from(v: Vec<Value>) -> Self {
Value::Array(v)
}
}
impl From<Vec<(Value, Value)>> for Value {
#[inline]
fn from(v: Vec<(Value, Value)>) -> Self {
Value::Map(v)
}
}
impl<V> FromIterator<V> for Value
where V: Into<Value> {
fn from_iter<I: IntoIterator<Item = V>>(iter: I) -> Self {
let v: Vec<Value> = iter.into_iter().map(|v| v.into()).collect();
Value::Array(v)
}
}
impl TryFrom<Value> for u64 {
type Error = Value;
fn try_from(val: Value) -> Result<Self, Self::Error> {
match val {
Value::Integer(n) => {
match n.as_u64() {
Some(i) => Ok(i),
None => Err(val)
}
}
v => Err(v),
}
}
}
impl TryFrom<Value> for i64 {
type Error = Value;
fn try_from(val: Value) -> Result<Self, Self::Error> {
match val {
Value::Integer(n) => {
match n.as_i64() {
Some(i) => Ok(i),
None => Err(val)
}
}
v => Err(v),
}
}
}
impl TryFrom<Value> for f64 {
type Error = Value;
fn try_from(val: Value) -> Result<Self, Self::Error> {
match val {
Value::Integer(n) => {
match n.as_f64() {
Some(i) => Ok(i),
None => Err(val)
}
}
Value::F32(n) => Ok(From::from(n)),
Value::F64(n) => Ok(n),
v => Err(v),
}
}
}
impl TryFrom<Value> for String {
type Error = Value;
fn try_from(val: Value) -> Result<Self, Self::Error> {
match val {
Value::String(Utf8String{ s: Ok(u)}) => {
Ok(u)
}
_ => Err(val)
}
}
}
macro_rules! impl_try_from {
($t: ty, $p: ident) => {
impl TryFrom<Value> for $t {
type Error = Value;
fn try_from(val: Value) -> Result<$t, Self::Error> {
match val {
Value::$p(v) => Ok(v),
v => Err(v)
}
}
}
};
}
impl_try_from!(bool, Boolean);
impl_try_from!(Vec<Value>, Array);
impl_try_from!(Vec<(Value, Value)>, Map);
impl_try_from!(Vec<u8>, Binary);
impl_try_from!(f32, F32);
impl_try_from!(Utf8String, String);
impl Display for Value {
#[cold]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match *self {
Value::Nil => f.write_str("nil"),
Value::Boolean(val) => Display::fmt(&val, f),
Value::Integer(ref val) => Display::fmt(&val, f),
Value::F32(val) => Display::fmt(&val, f),
Value::F64(val) => Display::fmt(&val, f),
Value::String(ref val) => Display::fmt(&val, f),
Value::Binary(ref val) => Debug::fmt(&val, f),
Value::Array(ref vec) => {
let res = vec.iter()
.map(|val| format!("{val}"))
.collect::<Vec<String>>()
.join(", ");
write!(f, "[{res}]")
}
Value::Map(ref vec) => {
write!(f, "{{")?;
match vec.iter().take(1).next() {
Some((k, v)) => {
write!(f, "{k}: {v}")?;
}
None => {
write!(f, "")?;
}
}
for (k, v) in vec.iter().skip(1) {
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> {
#[must_use]
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(|(k, v)| (k.to_owned(), v.to_owned())).collect())
}
ValueRef::Ext(ty, buf) => Value::Ext(ty, buf.to_vec()),
}
}
#[must_use]
pub fn index(&self, index: usize) -> &ValueRef<'_> {
self.as_array().and_then(|v| v.get(index)).unwrap_or(&NIL_REF)
}
#[must_use]
pub fn as_u64(&self) -> Option<u64> {
match *self {
ValueRef::Integer(ref n) => n.as_u64(),
_ => None,
}
}
#[must_use]
pub fn as_array(&self) -> Option<&Vec<ValueRef<'_>>> {
if let ValueRef::Array(ref array) = *self {
Some(array)
} else {
None
}
}
#[inline]
#[must_use]
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> {
#[inline]
fn from(v: u8) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<u16> for ValueRef<'a> {
#[inline]
fn from(v: u16) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<u32> for ValueRef<'a> {
#[inline]
fn from(v: u32) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<u64> for ValueRef<'a> {
#[inline]
fn from(v: u64) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<usize> for ValueRef<'a> {
#[inline]
fn from(v: usize) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<i8> for ValueRef<'a> {
#[inline]
fn from(v: i8) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<i16> for ValueRef<'a> {
#[inline]
fn from(v: i16) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<i32> for ValueRef<'a> {
#[inline]
fn from(v: i32) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<i64> for ValueRef<'a> {
#[inline]
fn from(v: i64) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<isize> for ValueRef<'a> {
#[inline]
fn from(v: isize) -> Self {
ValueRef::Integer(From::from(v))
}
}
impl<'a> From<f32> for ValueRef<'a> {
#[inline]
fn from(v: f32) -> Self {
ValueRef::F32(v)
}
}
impl<'a> From<f64> for ValueRef<'a> {
#[inline]
fn from(v: f64) -> Self {
ValueRef::F64(v)
}
}
impl<'a> From<&'a str> for ValueRef<'a> {
#[inline]
fn from(v: &'a str) -> Self {
ValueRef::String(Utf8StringRef::from(v))
}
}
impl<'a> From<&'a [u8]> for ValueRef<'a> {
#[inline]
fn from(v: &'a [u8]) -> Self {
ValueRef::Binary(v)
}
}
impl<'a> From<Vec<ValueRef<'a>>> for ValueRef<'a> {
#[inline]
fn from(v: Vec<ValueRef<'a>>) -> Self {
ValueRef::Array(v)
}
}
impl<'a, V> FromIterator<V> for ValueRef<'a>
where V: Into<ValueRef<'a>> {
fn from_iter<I: IntoIterator<Item = V>>(iter: I) -> Self {
let v: Vec<ValueRef<'a>> = iter.into_iter().map(|v| v.into()).collect();
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> TryFrom<ValueRef<'a>> for u64 {
type Error = ValueRef<'a>;
fn try_from(val: ValueRef<'a>) -> Result<Self, Self::Error> {
match val {
ValueRef::Integer(n) => match n.as_u64() {
Some(i) => Ok(i),
None => Err(val),
},
v => Err(v),
}
}
}
macro_rules! impl_try_from_ref {
($t: ty, $p: ident) => {
impl<'a> TryFrom<ValueRef<'a>> for $t {
type Error = ValueRef<'a>;
fn try_from(val: ValueRef<'a>) -> Result<$t, Self::Error> {
match val {
ValueRef::$p(v) => Ok(v),
v => Err(v)
}
}
}
};
}
impl_try_from_ref!(bool, Boolean);
impl_try_from_ref!(Vec<ValueRef<'a>>, Array);
impl_try_from_ref!(Vec<(ValueRef<'a>, ValueRef<'a>)>, Map);
impl_try_from_ref!(&'a [u8], Binary);
impl_try_from_ref!(f32, F32);
impl_try_from_ref!(Utf8StringRef<'a>, String);
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) => Display::fmt(&val, f),
ValueRef::Integer(ref val) => Display::fmt(&val, f),
ValueRef::F32(val) => Display::fmt(&val, f),
ValueRef::F64(val) => Display::fmt(&val, f),
ValueRef::String(ref val) => Display::fmt(&val, f),
ValueRef::Binary(ref val) => Debug::fmt(&val, f),
ValueRef::Array(ref vec) => {
let res = vec.iter()
.map(|val| format!("{val}"))
.collect::<Vec<String>>()
.join(", ");
write!(f, "[{res}]")
}
ValueRef::Map(ref vec) => {
write!(f, "{{")?;
match vec.iter().take(1).next() {
Some((k, v)) => {
write!(f, "{k}: {v}")?;
}
None => {
write!(f, "")?;
}
}
for (k, v) in vec.iter().skip(1) {
write!(f, ", {k}: {v}")?;
}
write!(f, "}}")
}
ValueRef::Ext(ty, data) => {
write!(f, "[{ty}, {data:?}]")
}
}
}
}