#![allow(dead_code)]
use deser::State;
use deser::de::{Deserialize, DeserializeOwned, Sink, SinkHandle, default_atom};
use deser::ext::ExtValue;
use deser::ser::{Emit, MapEmitter, SeqEmitter, Serialize, SerializeHandle};
use deser::{Atom, Error};
pub struct Chunked<'a> {
pub input: &'a [u8],
pub size: usize,
}
impl std::io::Read for Chunked<'_> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let len = self.size.min(buf.len()).min(self.input.len());
buf[..len].copy_from_slice(&self.input[..len]);
self.input = &self.input[len..];
Ok(len)
}
}
pub fn hex(s: &str) -> Vec<u8> {
let s: String = s.chars().filter(|c| !c.is_whitespace()).collect();
assert!(s.len().is_multiple_of(2), "odd hex string {:?}", s);
(0..s.len())
.step_by(2)
.map(|idx| u8::from_str_radix(&s[idx..idx + 2], 16).unwrap())
.collect()
}
pub fn to_hex(bytes: &[u8]) -> String {
bytes.iter().map(|b| format!("{:02x}", b)).collect()
}
pub fn de<T: DeserializeOwned>(s: &str) -> Result<T, Error> {
deser_msgpack::from_slice(&hex(s))
}
pub fn ser<T: Serialize>(value: &T) -> String {
to_hex(&deser_msgpack::to_vec(value).unwrap())
}
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
Null,
Bool(bool),
U64(u64),
I64(i64),
U128(u128),
I128(i128),
F32(f32),
F64(f64),
Str(String),
Bytes(Vec<u8>),
Array(Vec<Value>),
Map(Vec<(Value, Value)>),
Ext(ExtValue<'static>),
}
impl Value {
pub fn bytes(s: &str) -> Value {
Value::Bytes(hex(s))
}
pub fn ext<T: deser::ext::Extension>(value: T) -> Value {
Value::Ext(ExtValue::owned(value))
}
}
macro_rules! from_int {
($($ty:ty => $variant:ident),*) => {
$(impl From<$ty> for Value {
fn from(value: $ty) -> Value {
Value::$variant(value as _)
}
})*
};
}
from_int!(u8 => U64, u32 => U64, u64 => U64, i32 => I64, i64 => I64, u128 => U128, i128 => I128);
impl From<f32> for Value {
fn from(value: f32) -> Value {
Value::F32(value)
}
}
impl From<f64> for Value {
fn from(value: f64) -> Value {
Value::F64(value)
}
}
impl From<bool> for Value {
fn from(value: bool) -> Value {
Value::Bool(value)
}
}
impl From<&str> for Value {
fn from(value: &str) -> Value {
Value::Str(value.into())
}
}
impl<T: Into<Value>> From<Vec<T>> for Value {
fn from(value: Vec<T>) -> Value {
Value::Array(value.into_iter().map(Into::into).collect())
}
}
#[macro_export]
macro_rules! array {
($($value:expr),* $(,)?) => {
$crate::common::Value::Array(vec![$($crate::common::Value::from($value)),*])
};
}
#[macro_export]
macro_rules! map {
($($key:expr => $value:expr),* $(,)?) => {
$crate::common::Value::Map(vec![
$(($crate::common::Value::from($key), $crate::common::Value::from($value))),*
])
};
}
impl Serialize for Value {
fn serialize<'a>(this: &'a Self, state: &mut State) -> Result<Emit<'a>, Error> {
Ok(Emit::Atom(match *this {
Value::Null => Atom::Null,
Value::Bool(value) => Atom::Bool(value),
Value::U64(value) => Atom::U64(value),
Value::I64(value) => Atom::I64(value),
Value::U128(ref value) => Atom::Ext(ExtValue::borrowed(value)),
Value::I128(ref value) => Atom::Ext(ExtValue::borrowed(value)),
Value::F32(value) => Atom::F32(value),
Value::F64(value) => Atom::F64(value),
Value::Str(ref value) => Atom::Str(value.as_str().into()),
Value::Bytes(ref value) => Atom::Bytes(value.as_slice().into()),
Value::Ext(ref value) => Atom::Ext(value.as_borrowed()),
Value::Array(ref items) => return Ok(Emit::seq(ArrayEmitter(items.iter()), state)),
Value::Map(ref items) => {
return Ok(Emit::map(MapEntryEmitter(items.iter(), None), state));
}
}))
}
}
struct ArrayEmitter<'a>(std::slice::Iter<'a, Value>);
impl<'a> SeqEmitter for ArrayEmitter<'a> {
fn next(&mut self, _state: &mut State) -> Result<Option<SerializeHandle<'_>>, Error> {
Ok(self.0.next().map(SerializeHandle::to))
}
}
struct MapEntryEmitter<'a>(std::slice::Iter<'a, (Value, Value)>, Option<&'a Value>);
impl<'a> MapEmitter for MapEntryEmitter<'a> {
fn next_key(&mut self, _state: &mut State) -> Result<Option<SerializeHandle<'_>>, Error> {
Ok(self.0.next().map(|(key, value)| {
self.1 = Some(value);
SerializeHandle::to(key)
}))
}
fn next_value(&mut self, _state: &mut State) -> Result<SerializeHandle<'_>, Error> {
Ok(SerializeHandle::to(self.1.unwrap()))
}
}
impl<'de> Deserialize<'de> for Value {
fn deserialize_into<'out>(
out: &'out mut Option<Self>,
state: &mut State,
) -> SinkHandle<'out, 'de> {
SinkHandle::arena(
ValueSink {
out,
compound: None,
key: None,
value: None,
},
state,
)
}
}
enum Compound {
Array(Vec<Value>),
Map(Vec<(Value, Value)>),
}
struct ValueSink<'a> {
out: &'a mut Option<Value>,
compound: Option<Compound>,
key: Option<Value>,
value: Option<Value>,
}
impl<'a> ValueSink<'a> {
fn set(&mut self, value: Value) {
*self.out = Some(value);
}
fn flush(&mut self) {
match self.compound {
Some(Compound::Array(ref mut items)) => items.extend(self.value.take()),
Some(Compound::Map(ref mut items)) => {
if let (Some(key), Some(value)) = (self.key.take(), self.value.take()) {
items.push((key, value));
}
}
None => {}
}
}
}
impl<'a, 'de> Sink<'de> for ValueSink<'a> {
fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
let value = match atom {
Atom::Null => Value::Null,
Atom::Bool(value) => Value::Bool(value),
Atom::Str(value) | Atom::Lexical(value) => Value::Str(value.into_owned()),
Atom::Bytes(value) => Value::Bytes(value.into_owned()),
Atom::Char(value) => Value::Str(value.to_string()),
Atom::U64(value) => Value::U64(value),
Atom::I64(value) => Value::I64(value),
Atom::F32(value) => Value::F32(value),
Atom::F64(value) => Value::F64(value),
Atom::Ext(ref ext) if ext.is::<u128>() => Value::U128(*ext.downcast_ref().unwrap()),
Atom::Ext(ref ext) if ext.is::<i128>() => Value::I128(*ext.downcast_ref().unwrap()),
Atom::Ext(ref ext) => Value::Ext(ext.to_static()),
other => return default_atom(self, other, state),
};
self.set(value);
Ok(())
}
fn map(&mut self, _state: &mut State) -> Result<(), Error> {
self.compound = Some(Compound::Map(Vec::new()));
Ok(())
}
fn seq(&mut self, _state: &mut State) -> Result<(), Error> {
self.compound = Some(Compound::Array(Vec::new()));
Ok(())
}
fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
self.flush();
Ok(Value::deserialize_into(&mut self.key, state))
}
fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
if let Some(Compound::Array(_)) = self.compound {
self.flush();
}
Ok(Value::deserialize_into(&mut self.value, state))
}
fn finish(&mut self, _state: &mut State) -> Result<(), Error> {
self.flush();
match self.compound.take() {
Some(Compound::Array(items)) => self.set(Value::Array(items)),
Some(Compound::Map(items)) => self.set(Value::Map(items)),
None => {}
}
Ok(())
}
}