use std::borrow::Cow;
use std::cell::Cell;
use std::char;
use std::cmp::{Eq, Ord};
use std::fmt;
use std::hash::{BuildHasher, Hash};
use std::io::Read;
use std::str;
use std::usize;
use quick_error::ResultExt;
use io::{AsExtBytes, TransparentCursor};
use stream;
pub fn from_stream_copy<R : Read, T : Deserialize<R, style::Copying>>
(stream: &mut stream::Stream<R>, config: &Config) -> Result<T>
{
T::deserialize_body(&Context::top(config), stream)
}
pub fn from_stream_borrow<R : Read, T : Deserialize<R, style::ZeroCopy>>
(stream: &mut stream::Stream<R>, config: &Config) -> Result<T>
{
T::deserialize_body(&Context::top(config), stream)
}
pub fn from_reader<R : Read, T : Deserialize<R, style::Copying>>
(reader: R, config: &Config) -> Result<T>
{
let mut stream = stream::Stream::new(reader);
T::deserialize_body(&Context::top(config), &mut stream)
}
pub fn from_slice_copy<'a, T : Deserialize<TransparentCursor<&'a [u8]>,
style::Copying>>
(bytes: &'a [u8], config: &Config) -> Result<T>
{
let mut stream = stream::Stream::from_slice(bytes);
T::deserialize_body(&Context::top(config), &mut stream)
}
pub fn from_slice_borrow<'a, T : Deserialize<TransparentCursor<&'a [u8]>,
style::ZeroCopy>>
(bytes: &'a [u8], config: &Config) -> Result<T>
{
let mut stream = stream::Stream::from_slice(bytes);
T::deserialize_body(&Context::top(config), &mut stream)
}
quick_error! {
#[derive(Debug)]
pub enum Error {
Stream(wo: String, err: stream::Error) {
description(err.description())
display("{} at {}", err, wo)
cause(err)
context(wo: &'a Context<'a>, err: stream::Error) ->
(wo.to_string(), err)
}
RecursionLimitExceeded(wo: String) {
description("recursion limit exceeded")
display("recursion limit exceeded at {}", wo)
}
UnknownField(wo: String, tag: u8, pos: u64) {
description("unknown field encountered")
display("unknown field {} encountered at {}.{{{}}}", tag, wo, pos)
}
UnknownVariant(wo: String, variant: u64) {
description("unknown enum variant encountered")
display("unknown enum variant {} encountered at {}", variant, wo)
}
FieldOccursTooFewTimes(wo: String, min: u64) {
description("too few occurrences of field")
display("too few occurrences (min {}) of field at {}", min, wo)
}
FieldOccursTooManyTimes(wo: String, max: u64) {
description("too many occurrences of field")
display("too many occurrences (max {}) of field at {}", max, wo)
}
RequiredFieldMissing(wo: String) {
description("required field missing")
display("required field missing at {}", wo)
}
InvalidValue(wo: String,
err: Box<::std::error::Error + Send + Sync>) {
description(err.description())
display("{} at {}", err, wo)
}
InvalidValueMsg(wo: String, err: &'static str) {
description(err)
display("{} at {}", err, wo)
}
MaxCollectExceeded(wo: String) {
description("collection size sum limit exceeded")
display("collection size sum limit exceeded at {}", wo)
}
MaxBlobExceeded(wo: String) {
description("copied blob size sum limit exceeded")
display("copied blob size sum limit exceeded at {}", wo)
}
#[allow(missing_docs)]
#[doc(hidden)]
_NonExhaustive
}
}
pub type Result<T> = ::std::result::Result<T, Error>;
#[derive(Debug, Clone)]
pub struct Config {
pub recursion_limit: usize,
pub ignore_unknown_fields: bool,
pub max_blob: usize,
pub max_collect: usize,
_non_public: (),
}
impl Default for Config {
fn default() -> Self {
Config {
recursion_limit: 32,
ignore_unknown_fields: true,
max_blob: 65536,
max_collect: 256,
_non_public: (),
}
}
}
#[derive(Debug, Clone)]
pub struct Context<'a> {
pub next: Option<&'a Context<'a>>,
pub field: &'a str,
pub pos: u64,
pub depth: usize,
pub config: &'a Config,
stats: Cow<'a, ContextStats>,
_non_public: (),
}
#[derive(Debug, Clone, Default)]
struct ContextStats {
collected: Cell<usize>,
total_blob: Cell<usize>,
}
impl<'a> Context<'a> {
pub fn top(config: &'a Config) -> Self {
Context {
next: None,
field: "",
pos: 0,
depth: 0,
config: config,
stats: Cow::Owned(ContextStats::default()),
_non_public: (),
}
}
pub fn push(&'a self, field: &'a str, pos: u64) -> Result<Self> {
if self.depth >= self.config.recursion_limit {
Err(Error::RecursionLimitExceeded(self.to_string()))
} else {
Ok(Context {
next: Some(self),
field: field,
pos: pos,
depth: self.depth + 1,
config: self.config,
stats: Cow::Borrowed(&*self.stats),
_non_public: (),
})
}
}
pub fn push_tag(&'a self, name: &'a mut [u8;2], tag: u8, pos: u64)
-> Result<Self> {
name[0] = b'0' + tag / 10;
name[1] = b'0' + tag % 10;
Self::push(self, str::from_utf8(&name[..]).unwrap(), pos)
}
pub fn unknown_field<R>(&self, field: &stream::Field<R>)
-> Result<()> {
if self.config.ignore_unknown_fields {
Ok(())
} else {
Err(Error::UnknownField(self.to_string(), field.tag, field.pos))
}
}
pub fn collect(&self, n: usize) -> Result<()> {
if self.config.max_collect - self.stats.collected.get() < n {
Err(Error::MaxCollectExceeded(self.to_string()))
} else {
self.stats.collected.set(self.stats.collected.get() + 1);
Ok(())
}
}
pub fn blob(&self, n: u64) -> Result<()> {
if ((self.config.max_blob - self.stats.total_blob.get()) as u64) < n {
Err(Error::MaxBlobExceeded(self.to_string()))
} else {
self.stats.total_blob.set(
self.stats.total_blob.get() + (n as usize));
Ok(())
}
}
}
impl<'a> fmt::Display for Context<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref next) = self.next {
write!(f, "{}.{}{{{}}}", next, self.field, self.pos)
} else {
write!(f, "{}{{{}}}", self.field, self.pos)
}
}
}
macro_rules! des_struct_body {
(($context:expr, $stream:expr); ($ctor:expr); $(
$tag:tt : $field:ident: $t:ty,
)*) => { {
$(
let mut $field =
<<$t as Deserialize<R, STYLE>>::Accum as Default>::default();
)*
while let Some(mut _field) = $stream.next_field().context($context)? {
match _field.tag {
$(
$tag => {
let subcontext = $context.push(
stringify!($field), _field.pos)?;
<$t as Deserialize<R, STYLE>>::deserialize_field(
&mut $field, &subcontext, &mut _field)?;
},
)*
_ => {
$context.unknown_field(&_field)?;
_field.skip().context($context)?
},
}
}
$(
let subcontext = $context.push(stringify!($field), $stream.pos())?;
let $field = <$t as Deserialize<R, STYLE>>::finish(
$field, &subcontext)?;
)*
$ctor
} }
}
pub mod style {
pub struct Copying;
pub struct ZeroCopy;
}
pub trait Deserialize<R : Read, STYLE = style::Copying> : Sized {
type Accum : Default + Sized;
fn deserialize_body
(context: &Context, stream: &mut stream::Stream<R>)
-> Result<Self>
{
Ok(des_struct_body! {
(context, stream); (top);
1: top: Self,
})
}
fn deserialize_field
(accum: &mut Self::Accum, context: &Context,
field: &mut stream::Field<R>)
-> Result<()>;
fn deserialize_element
(context: &Context, field: &mut stream::Field<R>) -> Result<Self>
{
let mut accum = <Self::Accum as Default>::default();
Self::deserialize_field(&mut accum, context, field)?;
Self::finish(accum, context)
}
fn serialized_as_slice() -> bool { false }
#[allow(unused_variables)]
fn deserialize_vec
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<Vec<Self>>>
{ None }
#[allow(unused_variables)]
fn deserialize_slice
(dst: &mut [Self], context: &Context, field: &mut stream::Field<R>)
-> Option<Result<()>>
{ None }
#[allow(unused_variables)]
fn deserialize_array_0
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;0]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_1
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;1]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_2
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;2]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_3
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;3]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_4
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;4]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_5
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;5]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_6
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;6]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_7
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;7]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_8
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;8]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_9
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;9]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_10
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;10]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_11
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;11]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_12
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;12]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_13
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;13]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_14
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;14]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_15
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;15]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_16
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;16]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_17
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;17]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_18
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;18]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_19
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;19]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_20
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;20]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_21
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;21]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_22
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;22]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_23
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;23]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_24
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;24]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_25
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;25]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_26
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;26]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_27
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;27]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_28
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;28]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_29
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;29]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_30
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;30]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_31
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;31]>>
{ None }
#[doc(hidden)]
#[allow(missing_docs, unused_variables)]
fn deserialize_array_32
(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[Self;32]>>
{ None }
fn finish(accum: Self::Accum, context: &Context) -> Result<Self>;
}
macro_rules! des_unary {
(($($stuff:tt)*); |$context:ident, $field:ident| ($cvt:expr)) => {
$($stuff)* {
type Accum = Option<Self>;
fn deserialize_field(accum: &mut Option<Self>, $context: &Context,
$field: &mut stream::Field<R>)
-> Result<()> {
if accum.is_some() {
return Err(Error::FieldOccursTooManyTimes(
$context.to_string(), 1));
}
*accum = Some($cvt);
Ok(())
}
fn finish(accum: Option<Self>, $context: &Context) -> Result<Self> {
accum.ok_or_else(|| Error::RequiredFieldMissing(
$context.to_string()))
}
}
} }
des_unary! {
(impl<T : ?Sized, R : Read, STYLE> Deserialize<R, STYLE>
for ::std::marker::PhantomData<T>);
|context, field| (field.value.to_null().context(context)
.map(|_| ::std::marker::PhantomData)?)
}
des_unary! {
(impl<'a, R : Read + AsExtBytes<'a>> Deserialize<R, style::ZeroCopy>
for &'a [u8]);
|context, field| (field.value.to_blob().and_then(|b| b.ext_slice())
.context(context)?)
}
des_unary! {
(impl<'a, R : Read + AsExtBytes<'a>> Deserialize<R, style::ZeroCopy>
for &'a str);
|context, field| (
str::from_utf8(
field.value.to_blob().and_then(|b| b.ext_slice())
.context(context)?)
.map_err(|e| Error::InvalidValue(context.to_string(),
Box::new(e)))?)
}
des_unary! {
(impl<R : Read, STYLE> Deserialize<R, STYLE> for String);
|context, field| ({
let mut blob = field.value.to_blob().context(context)?;
context.blob(blob.len())?;
String::from_utf8(
blob.read_fully(context.config.max_blob).context(context)?)
.map_err(|e| Error::InvalidValue(context.to_string(),
Box::new(e)))?
})
}
macro_rules! des_boxed {
($($what:tt)*) => {
impl<R : Read, STYLE, T : Deserialize<R, STYLE>> Deserialize<R, STYLE>
for $($what)*<T> {
type Accum = T::Accum;
fn deserialize_body
(context: &Context, stream: &mut stream::Stream<R>)
-> Result<Self>
{
T::deserialize_body(context, stream).map($($what)*::new)
}
fn deserialize_field
(accum: &mut Self::Accum, context: &Context,
field: &mut stream::Field<R>)
-> Result<()>
{
T::deserialize_field(accum, context, field)
}
fn deserialize_element
(context: &Context, field: &mut stream::Field<R>) -> Result<Self>
{
T::deserialize_element(context, field).map($($what)*::new)
}
fn finish(accum: T::Accum, context: &Context) -> Result<Self> {
T::finish(accum, context).map($($what)*::new)
}
}
} }
des_boxed!(Box);
des_boxed!(::std::rc::Rc);
des_boxed!(::std::sync::Arc);
impl<'a, R : Read, T : ?Sized + ToOwned> Deserialize<R, style::Copying>
for Cow<'a, T> where T::Owned : Deserialize<R, style::Copying> {
type Accum = <T::Owned as Deserialize<R, style::Copying>>::Accum;
fn deserialize_body
(context: &Context, stream: &mut stream::Stream<R>)
-> Result<Self>
{
<T::Owned as Deserialize<R, style::Copying>>::
deserialize_body(context, stream).map(Cow::Owned)
}
fn deserialize_field
(accum: &mut Self::Accum, context: &Context,
field: &mut stream::Field<R>)
-> Result<()>
{
<T::Owned as Deserialize<R, style::Copying>>::
deserialize_field(accum, context, field)
}
fn deserialize_element
(context: &Context, field: &mut stream::Field<R>) -> Result<Self>
{
<T::Owned as Deserialize<R, style::Copying>>::
deserialize_element(context, field).map(Cow::Owned)
}
fn finish(accum: Self::Accum, context: &Context) -> Result<Self> {
<T::Owned as Deserialize<R, style::Copying>>::
finish(accum, context).map(Cow::Owned)
}
}
impl<'a, R : Read, T : ?Sized + ToOwned> Deserialize<R, style::ZeroCopy>
for Cow<'a, T> where &'a T : Deserialize<R, style::ZeroCopy> {
type Accum = <&'a T as Deserialize<R, style::ZeroCopy>>::Accum;
fn deserialize_body
(context: &Context, stream: &mut stream::Stream<R>)
-> Result<Self>
{
<&'a T as Deserialize<R, style::ZeroCopy>>::
deserialize_body(context, stream).map(Cow::Borrowed)
}
fn deserialize_field
(accum: &mut Self::Accum, context: &Context,
field: &mut stream::Field<R>)
-> Result<()>
{
<&'a T as Deserialize<R, style::ZeroCopy>>::
deserialize_field(accum, context, field)
}
fn deserialize_element
(context: &Context, field: &mut stream::Field<R>) -> Result<Self>
{
<&'a T as Deserialize<R, style::ZeroCopy>>::
deserialize_element(context, field).map(Cow::Borrowed)
}
fn finish(accum: Self::Accum, context: &Context) -> Result<Self> {
<&'a T as Deserialize<R, style::ZeroCopy>>::
finish(accum, context).map(Cow::Borrowed)
}
}
macro_rules! deser_bytes_as_array {
($meth:ident, $n:tt) => {
fn $meth(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<[u8;$n]>> {
fn imp<R : Read>(context: &Context,
field: &mut stream::Field<R>)
-> Result<[u8;$n]> {
let mut blob = field.value.to_blob().context(context)?;
if blob.remaining() != $n {
return Err(Error::InvalidValueMsg(
context.to_string(),
concat!("blob is not exactly ",
stringify!($n),
" bytes long")));
}
let mut selves = [0u8;$n];
blob.read_exact(&mut selves)
.map_err(|e| stream::Error::from(e))
.context(context)?;
Ok(selves)
}
Some(imp(context, field))
}
}
}
impl<R : Read, STYLE> Deserialize<R, STYLE> for u8 {
type Accum = Option<u8>;
fn deserialize_field(accum: &mut Option<Self>, context: &Context,
field: &mut stream::Field<R>)
-> Result<()> {
if accum.is_some() {
return Err(Error::FieldOccursTooManyTimes(
context.to_string(), 1));
}
*accum = Some(field.value.to_u8().context(context)?);
Ok(())
}
fn finish(accum: Option<Self>, context: &Context) -> Result<Self> {
accum.ok_or_else(|| Error::RequiredFieldMissing(
context.to_string()))
}
fn serialized_as_slice() -> bool { true }
fn deserialize_vec(context: &Context, field: &mut stream::Field<R>)
-> Option<Result<Vec<u8>>> {
fn dv<R : Read>(context: &Context, field: &mut stream::Field<R>)
-> Result<Vec<u8>> {
let mut blob = field.value.to_blob().context(context)?;
context.blob(blob.len())?;
Ok(blob.read_fully(context.config.max_blob).context(context)?)
}
Some(dv(context, field))
}
fn deserialize_slice(dst: &mut [u8], context: &Context,
field: &mut stream::Field<R>)
-> Option<Result<()>> {
let mut blob = match field.value.to_blob().context(context) {
Ok(blob) => blob,
Err(e) => return Some(Err(e.into())),
};
if blob.remaining() != (dst.len() as u64) {
return Some(Err(Error::InvalidValueMsg(
context.to_string(),
"blob is the not correct length")));
}
Some(blob.read_exact(dst).map(|_| ())
.map_err(stream::Error::from)
.context(context).map_err(Error::from))
}
deser_bytes_as_array!(deserialize_array_0, 0);
deser_bytes_as_array!(deserialize_array_1, 1);
deser_bytes_as_array!(deserialize_array_2, 2);
deser_bytes_as_array!(deserialize_array_3, 3);
deser_bytes_as_array!(deserialize_array_4, 4);
deser_bytes_as_array!(deserialize_array_5, 5);
deser_bytes_as_array!(deserialize_array_6, 6);
deser_bytes_as_array!(deserialize_array_7, 7);
deser_bytes_as_array!(deserialize_array_8, 8);
deser_bytes_as_array!(deserialize_array_9, 9);
deser_bytes_as_array!(deserialize_array_10, 10);
deser_bytes_as_array!(deserialize_array_11, 11);
deser_bytes_as_array!(deserialize_array_12, 12);
deser_bytes_as_array!(deserialize_array_13, 13);
deser_bytes_as_array!(deserialize_array_14, 14);
deser_bytes_as_array!(deserialize_array_15, 15);
deser_bytes_as_array!(deserialize_array_16, 16);
deser_bytes_as_array!(deserialize_array_17, 17);
deser_bytes_as_array!(deserialize_array_18, 18);
deser_bytes_as_array!(deserialize_array_19, 19);
deser_bytes_as_array!(deserialize_array_20, 20);
deser_bytes_as_array!(deserialize_array_21, 21);
deser_bytes_as_array!(deserialize_array_22, 22);
deser_bytes_as_array!(deserialize_array_23, 23);
deser_bytes_as_array!(deserialize_array_24, 24);
deser_bytes_as_array!(deserialize_array_25, 25);
deser_bytes_as_array!(deserialize_array_26, 26);
deser_bytes_as_array!(deserialize_array_27, 27);
deser_bytes_as_array!(deserialize_array_28, 28);
deser_bytes_as_array!(deserialize_array_29, 29);
deser_bytes_as_array!(deserialize_array_30, 30);
deser_bytes_as_array!(deserialize_array_31, 31);
deser_bytes_as_array!(deserialize_array_32, 32);
}
macro_rules! des_direct {
($ty:ty, $meth:ident) => {
des_unary! {
(impl<R : Read, STYLE> Deserialize<R, STYLE> for $ty);
|context, field| (field.value.$meth().context(context)?)
}
}
}
des_direct!(bool, to_bool);
des_direct!(i8, to_i8);
des_direct!(u16, to_u16);
des_direct!(i16, to_i16);
des_direct!(u32, to_u32);
des_direct!(i32, to_i32);
des_direct!(u64, to_u64);
des_direct!(i64, to_i64);
des_direct!(usize, to_usize);
des_direct!(isize, to_isize);
des_unary! {
(impl<R : Read, STYLE> Deserialize<R, STYLE> for char);
|context, field| (char::from_u32(field.value.to_u32().context(context)?)
.ok_or(Error::InvalidValueMsg(
context.to_string(),
"char not in valid range"))?)
}
#[allow(missing_docs)]
#[doc(hidden)]
pub enum ArrayAccum<O : Default, T> {
OneByOne(usize, O),
AllAtOnce(T),
}
impl<O : Default, T> Default for ArrayAccum<O, T> {
fn default() -> Self {
ArrayAccum::OneByOne(0, O::default())
}
}
impl<O : Default, T> ArrayAccum<O, T> {
fn has_one(&self) -> bool {
match *self {
ArrayAccum::OneByOne(0, _) => false,
_ => true,
}
}
}
macro_rules! des_small_array {
($n:tt, $arr_meth:ident $(, $count:expr)*) => {
impl<R : Read, STYLE, T : Deserialize<R, STYLE>>
Deserialize<R, STYLE> for [T;$n] {
type Accum = ArrayAccum<[Option<T>;$n],[T;$n]>;
fn deserialize_element
(context: &Context, field: &mut stream::Field<R>) -> Result<Self>
{
if let Some(handled) = T::$arr_meth(context, field) {
return handled;
}
Self::deserialize_body(
context, field.value.to_struct().context(context)?)
}
#[allow(unused_comparisons)]
fn deserialize_field
(accum: &mut Self::Accum, context: &Context,
field: &mut stream::Field<R>)
-> Result<()>
{
if let Some(handled) = T::$arr_meth(context, field) {
if accum.has_one() {
return Err(Error::FieldOccursTooManyTimes(
context.to_string(), 1));
} else {
*accum = ArrayAccum::AllAtOnce(handled?);
return Ok(());
}
}
match *accum {
ArrayAccum::AllAtOnce(_) =>
Err(Error::FieldOccursTooManyTimes(
context.to_string(), $n)),
ArrayAccum::OneByOne(ref mut count, ref mut dst) => {
if *count >= $n {
Err(Error::FieldOccursTooManyTimes(
context.to_string(), $n))
} else {
dst[*count] = Some(
T::deserialize_element(context, field)?);
*count += 1;
Ok(())
}
},
}
}
#[allow(unused_comparisons, unused_mut, unused_variables)]
fn finish(mut accum: Self::Accum, context: &Context)
-> Result<Self> {
match accum {
ArrayAccum::AllAtOnce(res) => Ok(res),
ArrayAccum::OneByOne(count, mut vals) => {
if count < $n {
if 0 == count {
Err(Error::RequiredFieldMissing(
context.to_string()))
} else {
Err(Error::FieldOccursTooFewTimes(
context.to_string(),
if T::serialized_as_slice() { 1 }
else { $n }))
}
} else {
Ok([$(vals[$count].take().unwrap()),*])
}
},
}
}
}
}
}
des_small_array!(0, deserialize_array_0);
des_small_array!(1, deserialize_array_1,
0);
des_small_array!(2, deserialize_array_2,
0, 1);
des_small_array!(3, deserialize_array_3,
0, 1, 2);
des_small_array!(4, deserialize_array_4,
0, 1, 2, 3);
des_small_array!(5, deserialize_array_5,
0, 1, 2, 3, 4);
des_small_array!(6, deserialize_array_6,
0, 1, 2, 3, 4, 5);
des_small_array!(7, deserialize_array_7,
0, 1, 2, 3, 4, 5, 6);
des_small_array!(8, deserialize_array_8,
0, 1, 2, 3, 4, 5, 6, 7);
des_small_array!(9, deserialize_array_9,
0, 1, 2, 3, 4, 5, 6, 7, 8);
des_small_array!(10, deserialize_array_10,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
des_small_array!(11, deserialize_array_11,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
des_small_array!(12, deserialize_array_12,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
des_small_array!(13, deserialize_array_13,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
des_small_array!(14, deserialize_array_14,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
des_small_array!(15, deserialize_array_15,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
des_small_array!(16, deserialize_array_16,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
des_small_array!(17, deserialize_array_17,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
des_small_array!(18, deserialize_array_18,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17);
des_small_array!(19, deserialize_array_19,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18);
des_small_array!(20, deserialize_array_20,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19);
des_small_array!(21, deserialize_array_21,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20);
des_small_array!(22, deserialize_array_22,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21);
des_small_array!(23, deserialize_array_23,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22);
des_small_array!(24, deserialize_array_24,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23);
des_small_array!(25, deserialize_array_25,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24);
des_small_array!(26, deserialize_array_26,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25);
des_small_array!(27, deserialize_array_27,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26);
des_small_array!(28, deserialize_array_28,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27);
des_small_array!(29, deserialize_array_29,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28);
des_small_array!(30, deserialize_array_30,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29);
des_small_array!(31, deserialize_array_31,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30);
des_small_array!(32, deserialize_array_32,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31);
#[allow(missing_docs)] #[doc(hidden)]
pub struct LargeArrayAccum<T>(usize, T);
macro_rules! des_large_array {
($n:expr) => {
impl<T : Copy + Default> Default for LargeArrayAccum<[T;$n]> {
fn default() -> Self {
LargeArrayAccum(0, [T::default();$n])
}
}
impl<R : Read, STYLE, T : Copy + Default + Deserialize<R, STYLE>>
Deserialize<R, STYLE> for [T;$n] {
type Accum = LargeArrayAccum<Self>;
fn deserialize_element
(context: &Context, field: &mut stream::Field<R>) -> Result<Self>
{
let mut special = [T::default(); $n];
if let Some(handled) = T::deserialize_slice(
&mut special, context, field)
{
handled?;
return Ok(special);
}
Self::deserialize_body(
context, field.value.to_struct().context(context)?)
}
fn deserialize_field
(accum: &mut Self::Accum, context: &Context,
field: &mut stream::Field<R>)
-> Result<()>
{
if let Some(handled) = T::deserialize_slice(
&mut accum.1, context, field)
{
handled?;
if 0 != accum.0 {
return Err(Error::FieldOccursTooManyTimes(
context.to_string(), 1));
} else {
accum.0 = $n;
return Ok(());
}
}
if accum.0 >= $n {
Err(Error::FieldOccursTooManyTimes(
context.to_string(), $n))
} else {
accum.1[accum.0] = T::deserialize_element(context, field)?;
accum.0 += 1;
Ok(())
}
}
fn finish(accum: Self::Accum, context: &Context)
-> Result<Self> {
if accum.0 < $n {
if 0 == accum.0 {
Err(Error::RequiredFieldMissing(
context.to_string()))
} else {
Err(Error::FieldOccursTooFewTimes(
context.to_string(),
if T::serialized_as_slice() { 1 }
else { $n }))
}
} else {
Ok(accum.1)
}
}
}
}
}
des_large_array!(64);
des_large_array!(128);
des_large_array!(256);
des_large_array!(512);
des_large_array!(1024);
des_large_array!(2048);
des_large_array!(4096);
des_large_array!(8192);
des_large_array!(16384);
des_large_array!(32768);
des_large_array!(65536);
des_large_array!(131072);
des_large_array!(262144);
des_large_array!(524288);
des_large_array!(1048576);
des_large_array!(2097152);
des_large_array!(4194304);
des_large_array!(8388608);
des_large_array!(16777216);
macro_rules! des_struct {
(($($stuff:tt)*);
($ctor:expr);
$($tag:tt : $field:ident: $t:ty,)*) => { $($stuff)* {
type Accum = Option<Self>;
fn deserialize_body(context: &Context,
stream: &mut stream::Stream<R>)
-> Result<Self> {
Ok(des_struct_body! {
(context, stream); ($ctor);
$($tag: $field: $t,)*
})
}
fn deserialize_field(accum: &mut Option<Self>,
context: &Context,
field: &mut stream::Field<R>)
-> Result<()> {
if accum.is_some() {
return Err(Error::FieldOccursTooManyTimes(
context.to_string(), 1));
}
*accum = Some(
<Self as Deserialize<R, STYLE>>
::deserialize_element(context, field)?);
Ok(())
}
fn deserialize_element(context: &Context,
field: &mut stream::Field<R>)
-> Result<Self> {
<Self as Deserialize<R, STYLE>>::deserialize_body(
context, field.value.to_struct().context(context)?)
}
fn finish(accum: Option<Self>, context: &Context)
-> Result<Self> {
accum.ok_or_else(|| Error::RequiredFieldMissing(
context.to_string()))
}
} }
}
macro_rules! des_tuple {
($($ix:tt: $name:ident: $tname:ident),*) => { des_struct! {
(impl <R : Read, STYLE, $($tname : Deserialize<R, STYLE>),*>
Deserialize<R, STYLE> for ($($tname,)*));
(($($name,)*));
$($ix : $name : $tname,)*
} }
}
des_tuple!();
des_tuple!(1: field_0: F0);
des_tuple!(1: field_0: F0, 2: field_1: F1);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2, 4: field_3: F3);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2, 4: field_3: F3,
5: field_4: F4);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2, 4: field_3: F3,
5: field_4: F4, 6: field_5: F5);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2, 4: field_3: F3,
5: field_4: F4, 6: field_5: F5, 7: field_6: F6);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2, 4: field_3: F3,
5: field_4: F4, 6: field_5: F5, 7: field_6: F6, 8: field_7: F7);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2, 4: field_3: F3,
5: field_4: F4, 6: field_5: F5, 7: field_6: F6, 8: field_7: F7,
9: field_8: F8);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2, 4: field_3: F3,
5: field_4: F4, 6: field_5: F5, 7: field_6: F6, 8: field_7: F7,
9: field_8: F8, 10: field_9: F9);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2, 4: field_3: F3,
5: field_4: F4, 6: field_5: F5, 7: field_6: F6, 8: field_7: F7,
9: field_8: F8, 10: field_9: F9, 11: field_10: F10);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2, 4: field_3: F3,
5: field_4: F4, 6: field_5: F5, 7: field_6: F6, 8: field_7: F7,
9: field_8: F8, 10: field_9: F9, 11: field_10: F10,
12: field_11: F11);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2, 4: field_3: F3,
5: field_4: F4, 6: field_5: F5, 7: field_6: F6, 8: field_7: F7,
9: field_8: F8, 10: field_9: F9, 11: field_10: F10,
12: field_11: F11, 13: field_12: F12);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2, 4: field_3: F3,
5: field_4: F4, 6: field_5: F5, 7: field_6: F6, 8: field_7: F7,
9: field_8: F8, 10: field_9: F9, 11: field_10: F10,
12: field_11: F11, 13: field_12: F12, 14: field_13: F13);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2, 4: field_3: F3,
5: field_4: F4, 6: field_5: F5, 7: field_6: F6, 8: field_7: F7,
9: field_8: F8, 10: field_9: F9, 11: field_10: F10,
12: field_11: F11, 13: field_12: F12, 14: field_13: F13,
15: field_14: F14);
des_tuple!(1: field_0: F0, 2: field_1: F1, 3: field_2: F2, 4: field_3: F3,
5: field_4: F4, 6: field_5: F5, 7: field_6: F6, 8: field_7: F7,
9: field_8: F8, 10: field_9: F9, 11: field_10: F10,
12: field_11: F11, 13: field_12: F12, 14: field_13: F13,
15: field_14: F14, 16: field_15: F15);
impl<R : Read, STYLE, T : Deserialize<R, STYLE>>
Deserialize<R, STYLE> for Vec<T> {
type Accum = (bool, Self);
fn deserialize_element
(context: &Context, field: &mut stream::Field<R>) -> Result<Self>
{
if let Some(handled) = T::deserialize_vec(context, field) {
return handled;
}
Self::deserialize_body(
context, field.value.to_struct().context(context)?)
}
fn deserialize_field
(accum: &mut (bool, Self), context: &Context,
field: &mut stream::Field<R>) -> Result<()>
{
if let Some(handled) = T::deserialize_vec(context, field) {
if accum.0 {
return Err(Error::FieldOccursTooManyTimes(
context.to_string(), 1));
} else {
accum.1 = handled?;
accum.0 = true;
return Ok(());
}
}
context.collect(1)?;
accum.1.push(T::deserialize_element(context, field)?);
Ok(())
}
fn finish(accum: (bool, Self), context: &Context) -> Result<Self> {
if T::serialized_as_slice() && !accum.0 {
Err(Error::RequiredFieldMissing(context.to_string()))
} else {
Ok(accum.1)
}
}
}
macro_rules! des_push_seq {
(($($stuff:tt)*); $meth:ident) => {
$($stuff)* {
type Accum = Self;
fn deserialize_element
(context: &Context, field: &mut stream::Field<R>) -> Result<Self>
{
Self::deserialize_body(
context, field.value.to_struct().context(context)?)
}
fn deserialize_field
(accum: &mut Self, context: &Context,
field: &mut stream::Field<R>) -> Result<()>
{
context.collect(1)?;
accum.$meth(T::deserialize_element(context, field)?);
Ok(())
}
fn finish(accum: Self, _: &Context) -> Result<Self> {
Ok(accum)
}
}
}
}
des_push_seq!((impl<R : Read, STYLE, T : Deserialize<R, STYLE>>
Deserialize<R, STYLE> for ::std::collections::LinkedList<T>);
push_back);
des_push_seq!((impl<R : Read, STYLE, T : Deserialize<R, STYLE>>
Deserialize<R, STYLE> for ::std::collections::VecDeque<T>);
push_back);
des_push_seq!((impl<R : Read, STYLE, T : Deserialize<R, STYLE> + Ord>
Deserialize<R, STYLE> for ::std::collections::BTreeSet<T>);
insert);
des_push_seq!((impl<R : Read, STYLE, T : Deserialize<R, STYLE> + Hash + Eq,
H : BuildHasher + Default>
Deserialize<R, STYLE> for ::std::collections::HashSet<T, H>);
insert);
des_push_seq!((impl<R : Read, STYLE, T : Deserialize<R, STYLE> + Ord>
Deserialize<R, STYLE> for ::std::collections::BinaryHeap<T>);
push);
impl<R : Read, STYLE, T : Deserialize<R, STYLE>> Deserialize<R, STYLE>
for Option<T> {
type Accum = Self;
fn deserialize_element
(context: &Context, field: &mut stream::Field<R>) -> Result<Self>
{
Self::deserialize_body(
context, field.value.to_struct().context(context)?)
}
fn deserialize_field
(accum: &mut Self, context: &Context,
field: &mut stream::Field<R>) -> Result<()>
{
if accum.is_some() {
Err(Error::FieldOccursTooManyTimes(
context.to_string(), 1))
} else {
*accum = Some(T::deserialize_element(context, field)?);
Ok(())
}
}
fn finish(accum: Self, _: &Context) -> Result<Self> {
Ok(accum)
}
}
macro_rules! des_map {
($($stuff:tt)*) => {
$($stuff)* {
type Accum = Self;
fn deserialize_element
(context: &Context, field: &mut stream::Field<R>) -> Result<Self>
{
Self::deserialize_body(
context, field.value.to_struct().context(context)?)
}
fn deserialize_field
(accum: &mut Self, context: &Context,
field: &mut stream::Field<R>) -> Result<()>
{
context.collect(1)?;
let (k, v) = <(K, V) as Deserialize<R, STYLE>>::
deserialize_element(context, field)?;
accum.insert(k, v);
Ok(())
}
fn finish(accum: Self, _: &Context) -> Result<Self> {
Ok(accum)
}
}
}
}
des_map!(impl<R : Read, STYLE, K : Deserialize<R, STYLE> + Hash + Eq,
V : Deserialize<R, STYLE>, H : BuildHasher + Default>
Deserialize<R, STYLE> for ::std::collections::HashMap<K, V, H>);
des_map!(impl<R : Read, STYLE, K : Deserialize<R, STYLE> + Ord,
V : Deserialize<R, STYLE>>
Deserialize<R, STYLE> for ::std::collections::BTreeMap<K, V>);