use std::io;
use std::io::{Read, Cursor};
use std::result::Result;
use std::str::{Utf8Error, from_utf8};
use byteorder;
use byteorder::ReadBytesExt;
use super::Marker;
#[derive(Debug)]
pub enum ReadError {
UnexpectedEOF,
Io(io::Error),
}
impl From<io::Error> for ReadError {
fn from(err: io::Error) -> ReadError {
ReadError::Io(err)
}
}
impl From<byteorder::Error> for ReadError {
fn from(err: byteorder::Error) -> ReadError {
match err {
byteorder::Error::UnexpectedEOF => ReadError::UnexpectedEOF,
byteorder::Error::Io(err) => ReadError::Io(err),
}
}
}
#[derive(Debug)]
pub enum MarkerReadError {
UnexpectedEOF,
Io(io::Error),
}
impl From<byteorder::Error> for MarkerReadError {
fn from(err: byteorder::Error) -> MarkerReadError {
match err {
byteorder::Error::UnexpectedEOF => MarkerReadError::UnexpectedEOF,
byteorder::Error::Io(err) => MarkerReadError::Io(err),
}
}
}
impl From<MarkerReadError> for ReadError {
fn from(err: MarkerReadError) -> ReadError {
match err {
MarkerReadError::UnexpectedEOF => ReadError::UnexpectedEOF,
MarkerReadError::Io(err) => ReadError::Io(err),
}
}
}
#[derive(Debug)]
pub enum FixedValueReadError {
UnexpectedEOF,
Io(io::Error),
TypeMismatch(Marker),
}
impl From<MarkerReadError> for FixedValueReadError {
fn from(err: MarkerReadError) -> FixedValueReadError {
match err {
MarkerReadError::UnexpectedEOF => FixedValueReadError::UnexpectedEOF,
MarkerReadError::Io(err) => FixedValueReadError::Io(err),
}
}
}
#[derive(Debug)]
pub enum ValueReadError {
InvalidMarkerRead(ReadError),
InvalidDataRead(ReadError),
TypeMismatch(Marker),
}
impl From<MarkerReadError> for ValueReadError {
fn from(err: MarkerReadError) -> ValueReadError {
ValueReadError::InvalidMarkerRead(From::from(err))
}
}
#[derive(Debug)]
pub enum DecodeStringError<'a> {
InvalidMarkerRead(ReadError),
InvalidDataRead(ReadError),
TypeMismatch(Marker),
BufferSizeTooSmall(u32),
InvalidDataCopy(&'a [u8], ReadError),
InvalidUtf8(&'a [u8], Utf8Error),
}
impl<'a> From<ValueReadError> for DecodeStringError<'a> {
fn from(err: ValueReadError) -> DecodeStringError<'a> {
match err {
ValueReadError::InvalidMarkerRead(err) => DecodeStringError::InvalidMarkerRead(err),
ValueReadError::InvalidDataRead(err) => DecodeStringError::InvalidDataRead(err),
ValueReadError::TypeMismatch(marker) => DecodeStringError::TypeMismatch(marker),
}
}
}
fn read_marker<R>(rd: &mut R) -> Result<Marker, MarkerReadError>
where R: Read
{
match rd.read_u8() {
Ok(val) => Ok(Marker::from_u8(val)),
Err(err) => Err(From::from(err)),
}
}
pub fn read_nil<R>(rd: &mut R) -> Result<(), FixedValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::Null => Ok(()),
marker => Err(FixedValueReadError::TypeMismatch(marker))
}
}
pub fn read_bool<R>(rd: &mut R) -> Result<bool, FixedValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::True => Ok(true),
Marker::False => Ok(false),
marker => Err(FixedValueReadError::TypeMismatch(marker))
}
}
pub fn read_pfix<R>(rd: &mut R) -> Result<u8, FixedValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::PositiveFixnum(val) => Ok(val),
marker => Err(FixedValueReadError::TypeMismatch(marker)),
}
}
pub fn read_nfix<R>(rd: &mut R) -> Result<i8, FixedValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::NegativeFixnum(val) => Ok(val),
marker => Err(FixedValueReadError::TypeMismatch(marker)),
}
}
macro_rules! make_read_data_fn {
(deduce, $reader:ident, $decoder:ident, 0)
=> ($reader.$decoder(););
(deduce, $reader:ident, $decoder:ident, 1)
=> ($reader.$decoder::<byteorder::BigEndian>(););
(gen, $t:ty, $d:tt, $name:ident, $decoder:ident) => {
fn $name<R>(rd: &mut R) -> Result<$t, ValueReadError>
where R: Read
{
match make_read_data_fn!(deduce, rd, $decoder, $d) {
Ok(data) => Ok(data),
Err(err) => Err(ValueReadError::InvalidDataRead(From::from(err))),
}
}
};
(u8, $name:ident, $decoder:ident) => (make_read_data_fn!(gen, u8, 0, $name, $decoder););
(i8, $name:ident, $decoder:ident) => (make_read_data_fn!(gen, i8, 0, $name, $decoder););
($t:ty, $name:ident, $decoder:ident) => (make_read_data_fn!(gen, $t, 1, $name, $decoder););
}
make_read_data_fn!(u8, read_data_u8, read_u8);
make_read_data_fn!(u16, read_data_u16, read_u16);
make_read_data_fn!(u32, read_data_u32, read_u32);
make_read_data_fn!(u64, read_data_u64, read_u64);
make_read_data_fn!(i8, read_data_i8, read_i8);
make_read_data_fn!(i16, read_data_i16, read_i16);
make_read_data_fn!(i32, read_data_i32, read_i32);
make_read_data_fn!(i64, read_data_i64, read_i64);
make_read_data_fn!(f32, read_data_f32, read_f32);
make_read_data_fn!(f64, read_data_f64, read_f64);
pub fn read_u8<R>(rd: &mut R) -> Result<u8, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::U8 => Ok(try!(read_data_u8(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_u16<R>(rd: &mut R) -> Result<u16, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::U16 => Ok(try!(read_data_u16(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_u32<R>(rd: &mut R) -> Result<u32, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::U32 => Ok(try!(read_data_u32(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_u64<R>(rd: &mut R) -> Result<u64, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::U64 => Ok(try!(read_data_u64(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_i8<R>(rd: &mut R) -> Result<i8, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::I8 => Ok(try!(read_data_i8(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_i16<R>(rd: &mut R) -> Result<i16, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::I16 => Ok(try!(read_data_i16(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_i32<R>(rd: &mut R) -> Result<i32, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::I32 => Ok(try!(read_data_i32(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_i64<R>(rd: &mut R) -> Result<i64, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::I64 => Ok(try!(read_data_i64(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_u8_loosely<R>(rd: &mut R) -> Result<u8, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::PositiveFixnum(val) => Ok(val),
Marker::U8 => Ok(try!(read_data_u8(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_u16_loosely<R>(rd: &mut R) -> Result<u16, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::PositiveFixnum(val) => Ok(val as u16),
Marker::U8 => Ok(try!(read_data_u8(rd)) as u16),
Marker::U16 => Ok(try!(read_data_u16(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_u32_loosely<R>(rd: &mut R) -> Result<u32, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::PositiveFixnum(val) => Ok(val as u32),
Marker::U8 => Ok(try!(read_data_u8(rd)) as u32),
Marker::U16 => Ok(try!(read_data_u16(rd)) as u32),
Marker::U32 => Ok(try!(read_data_u32(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_u64_loosely<R>(rd: &mut R) -> Result<u64, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::PositiveFixnum(val) => Ok(val as u64),
Marker::U8 => Ok(try!(read_data_u8(rd)) as u64),
Marker::U16 => Ok(try!(read_data_u16(rd)) as u64),
Marker::U32 => Ok(try!(read_data_u32(rd)) as u64),
Marker::U64 => Ok(try!(read_data_u64(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_i8_loosely<R>(rd: &mut R) -> Result<i8, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::NegativeFixnum(val) => Ok(val),
Marker::I8 => Ok(try!(read_data_i8(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_i16_loosely<R>(rd: &mut R) -> Result<i16, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::NegativeFixnum(val) => Ok(val as i16),
Marker::I8 => Ok(try!(read_data_i8(rd)) as i16),
Marker::I16 => Ok(try!(read_data_i16(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_i32_loosely<R>(rd: &mut R) -> Result<i32, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::NegativeFixnum(val) => Ok(val as i32),
Marker::I8 => Ok(try!(read_data_i8(rd)) as i32),
Marker::I16 => Ok(try!(read_data_i16(rd)) as i32),
Marker::I32 => Ok(try!(read_data_i32(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_i64_loosely<R>(rd: &mut R) -> Result<i64, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::NegativeFixnum(val) => Ok(val as i64),
Marker::I8 => Ok(try!(read_data_i8(rd)) as i64),
Marker::I16 => Ok(try!(read_data_i16(rd)) as i64),
Marker::I32 => Ok(try!(read_data_i32(rd)) as i64),
Marker::I64 => Ok(try!(read_data_i64(rd))),
marker => Err(ValueReadError::TypeMismatch(marker)),
}
}
pub fn read_f32<R>(rd: &mut R) -> Result<f32, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::F32 => Ok(try!(read_data_f32(rd))),
marker => Err(ValueReadError::TypeMismatch(marker))
}
}
pub fn read_f64<R>(rd: &mut R) -> Result<f64, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::F64 => Ok(try!(read_data_f64(rd))),
marker => Err(ValueReadError::TypeMismatch(marker))
}
}
pub fn read_str_len<R>(rd: &mut R) -> Result<u32, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::FixedString(size) => Ok(size as u32),
Marker::Str8 => Ok(try!(read_data_u8(rd)) as u32),
Marker::Str16 => Ok(try!(read_data_u16(rd)) as u32),
Marker::Str32 => Ok(try!(read_data_u32(rd))),
marker => Err(ValueReadError::TypeMismatch(marker))
}
}
pub fn read_str<'r, R>(rd: &mut R, mut buf: &'r mut [u8]) -> Result<&'r str, DecodeStringError<'r>>
where R: Read
{
let len = try!(read_str_len(rd));
let ulen = len as usize;
if buf.len() < ulen {
return Err(DecodeStringError::BufferSizeTooSmall(len))
}
read_str_data(rd, len, &mut buf[0..ulen])
}
fn read_str_data<'r, R>(rd: &mut R, len: u32, buf: &'r mut[u8]) -> Result<&'r str, DecodeStringError<'r>>
where R: Read
{
debug_assert_eq!(len as usize, buf.len());
let mut cur = Cursor::new(buf);
match io::copy(&mut rd.take(len as u64), &mut cur) {
Ok(size) if size == len as u64 => {
let buf = cur.into_inner();
match from_utf8(buf) {
Ok(decoded) => Ok(decoded),
Err(err) => Err(DecodeStringError::InvalidUtf8(buf, err)),
}
}
Ok(size) => {
let buf = cur.into_inner();
Err(DecodeStringError::InvalidDataCopy(&buf[..size as usize], ReadError::UnexpectedEOF))
}
Err(err) => Err(DecodeStringError::InvalidDataRead(From::from(err))),
}
}
pub fn read_str_ref(rd: &[u8]) -> Result<&[u8], DecodeStringError> {
let mut cur = io::Cursor::new(rd);
let len = try!(read_str_len(&mut cur));
let start = cur.position() as usize;
Ok(&rd[start .. start + len as usize])
}
pub fn read_array_size<R>(rd: &mut R) -> Result<u32, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::FixedArray(size) => Ok(size as u32),
Marker::Array16 => Ok(try!(read_data_u16(rd)) as u32),
Marker::Array32 => Ok(try!(read_data_u32(rd))),
marker => Err(ValueReadError::TypeMismatch(marker))
}
}
pub fn read_map_size<R>(rd: &mut R) -> Result<u32, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::FixedMap(size) => Ok(size as u32),
Marker::Map16 => Ok(try!(read_data_u16(rd)) as u32),
Marker::Map32 => Ok(try!(read_data_u32(rd))),
marker => Err(ValueReadError::TypeMismatch(marker))
}
}
pub fn read_bin_len<R>(rd: &mut R) -> Result<u32, ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::Bin8 => Ok(try!(read_data_u8(rd)) as u32),
Marker::Bin16 => Ok(try!(read_data_u16(rd)) as u32),
Marker::Bin32 => Ok(try!(read_data_u32(rd))),
marker => Err(ValueReadError::TypeMismatch(marker))
}
}
pub fn read_bin_borrow(rd: &[u8]) -> Result<&[u8], ValueReadError> {
let mut cur = io::Cursor::new(rd);
let len = try!(read_bin_len(&mut cur)) as usize;
let pos = cur.position() as usize;
if rd.len() < pos + len {
Err(ValueReadError::InvalidDataRead(ReadError::UnexpectedEOF))
} else {
Ok(&rd[pos .. pos + len])
}
}
pub fn read_fixext1<R>(rd: &mut R) -> Result<(i8, u8), ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::FixExt1 => {
let id = try!(read_data_i8(rd));
let data = try!(read_data_u8(rd));
Ok((id, data))
}
marker => Err(ValueReadError::TypeMismatch(marker))
}
}
pub fn read_fixext2<R>(rd: &mut R) -> Result<(i8, u16), ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::FixExt2 => {
let id = try!(read_data_i8(rd));
let data = try!(read_data_u16(rd));
Ok((id, data))
}
marker => Err(ValueReadError::TypeMismatch(marker))
}
}
pub fn read_fixext4<R>(rd: &mut R) -> Result<(i8, [u8; 4]), ValueReadError>
where R: Read
{
use std::mem;
match try!(read_marker(rd)) {
Marker::FixExt4 => {
let id = try!(read_data_i8(rd));
match rd.read_u32::<byteorder::LittleEndian>() {
Ok(data) => {
let out : [u8; 4] = unsafe { mem::transmute(data) };
Ok((id, out))
}
Err(err) => Err(ValueReadError::InvalidDataRead(From::from(err))),
}
}
marker => Err(ValueReadError::TypeMismatch(marker))
}
}
fn read_fixext8<R>(rd: &mut R) -> Result<(i8, [u8; 8]), ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::FixExt8 => {
let id = try!(read_data_i8(rd));
let mut out = [0u8; 8];
match io::copy(&mut rd.take(8), &mut &mut out[..]) {
Ok(8) => Ok((id, out)),
_ => unimplemented!()
}
}
marker => Err(ValueReadError::TypeMismatch(marker))
}
}
fn read_fixext16<R>(rd: &mut R) -> Result<(i8, [u8; 16]), ValueReadError>
where R: Read
{
match try!(read_marker(rd)) {
Marker::FixExt16 => {
let id = try!(read_data_i8(rd));
let mut out = [0u8; 16];
match io::copy(&mut rd.take(16), &mut &mut out[..]) {
Ok(16) => Ok((id, out)),
_ => unimplemented!()
}
}
marker => Err(ValueReadError::TypeMismatch(marker))
}
}
#[derive(Debug, PartialEq)]
pub struct ExtMeta {
pub typeid: i8,
pub size: u32,
}
pub fn read_ext_meta<R>(rd: &mut R) -> Result<ExtMeta, ValueReadError>
where R: Read
{
let size = match try!(read_marker(rd)) {
Marker::FixExt1 => 1,
Marker::FixExt2 => 2,
Marker::FixExt4 => 4,
Marker::FixExt8 => 8,
Marker::FixExt16 => 16,
Marker::Ext8 => try!(read_data_u8(rd)) as u32,
Marker::Ext16 => try!(read_data_u16(rd)) as u32,
Marker::Ext32 => try!(read_data_u32(rd)),
marker => return Err(ValueReadError::TypeMismatch(marker))
};
let typeid = try!(read_data_i8(rd));
let meta = ExtMeta { typeid: typeid, size: size };
Ok(meta)
}
mod value {
}
pub mod serialize {
use std::convert::From;
use std::io::Read;
use std::result;
use serialize;
use super::super::Marker;
use super::{
ReadError,
FixedValueReadError,
ValueReadError,
DecodeStringError,
read_nil,
read_bool,
read_u8_loosely,
read_u16_loosely,
read_u32_loosely,
read_u64_loosely,
read_i8_loosely,
read_i16_loosely,
read_i32_loosely,
read_i64_loosely,
read_f32,
read_f64,
read_str_len,
read_str_data,
read_array_size,
read_map_size,
};
#[derive(Debug)]
pub enum Error {
TypeMismatch(Marker),
InvalidMarkerRead(ReadError),
InvalidDataRead(ReadError),
LengthMismatch(u32),
Uncategorized(String),
}
impl From<FixedValueReadError> for Error {
fn from(err: FixedValueReadError) -> Error {
match err {
FixedValueReadError::UnexpectedEOF => Error::InvalidMarkerRead(ReadError::UnexpectedEOF),
FixedValueReadError::Io(err) => Error::InvalidMarkerRead(ReadError::Io(err)),
FixedValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker),
}
}
}
impl From<ValueReadError> for Error {
fn from(err: ValueReadError) -> Error {
match err {
ValueReadError::TypeMismatch(marker) => Error::TypeMismatch(marker),
ValueReadError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err),
ValueReadError::InvalidDataRead(err) => Error::InvalidDataRead(err),
}
}
}
impl<'a> From<DecodeStringError<'a>> for Error {
fn from(err: DecodeStringError) -> Error {
match err {
DecodeStringError::InvalidMarkerRead(err) => Error::InvalidMarkerRead(err),
DecodeStringError::InvalidDataRead(..) => Error::Uncategorized("InvalidDataRead".to_string()),
DecodeStringError::TypeMismatch(..) => Error::Uncategorized("TypeMismatch".to_string()),
DecodeStringError::BufferSizeTooSmall(..) => Error::Uncategorized("BufferSizeTooSmall".to_string()),
DecodeStringError::InvalidDataCopy(..) => Error::Uncategorized("InvalidDataCopy".to_string()),
DecodeStringError::InvalidUtf8(..) => Error::Uncategorized("InvalidUtf8".to_string()),
}
}
}
pub type Result<T> = result::Result<T, Error>;
pub struct Decoder<R: Read> {
rd: R,
}
impl<R: Read> Decoder<R> {
pub fn new(rd: R) -> Decoder<R> {
Decoder {
rd: rd
}
}
}
impl<R: Read> serialize::Decoder for Decoder<R> {
type Error = Error;
fn read_nil(&mut self) -> Result<()> {
Ok(try!(read_nil(&mut self.rd)))
}
fn read_bool(&mut self) -> Result<bool> {
Ok(try!(read_bool(&mut self.rd)))
}
fn read_u8(&mut self) -> Result<u8> {
Ok(try!(read_u8_loosely(&mut self.rd)))
}
fn read_u16(&mut self) -> Result<u16> {
Ok(try!(read_u16_loosely(&mut self.rd)))
}
fn read_u32(&mut self) -> Result<u32> {
Ok(try!(read_u32_loosely(&mut self.rd)))
}
fn read_u64(&mut self) -> Result<u64> {
Ok(try!(read_u64_loosely(&mut self.rd)))
}
fn read_usize(&mut self) -> Result<usize> {
let v = try!(self.read_u64());
Ok(v as usize)
}
fn read_i8(&mut self) -> Result<i8> {
Ok(try!(read_i8_loosely(&mut self.rd)))
}
fn read_i16(&mut self) -> Result<i16> {
Ok(try!(read_i16_loosely(&mut self.rd)))
}
fn read_i32(&mut self) -> Result<i32> {
Ok(try!(read_i32_loosely(&mut self.rd)))
}
fn read_i64(&mut self) -> Result<i64> {
Ok(try!(read_i64_loosely(&mut self.rd)))
}
fn read_isize(&mut self) -> Result<isize> {
Ok(try!(self.read_i64()) as isize)
}
fn read_f32(&mut self) -> Result<f32> {
Ok(try!(read_f32(&mut self.rd)))
}
fn read_f64(&mut self) -> Result<f64> {
Ok(try!(read_f64(&mut self.rd)))
}
fn read_char(&mut self) -> Result<char> {
let mut res = try!(self.read_str());
if res.len() == 1 {
Ok(res.pop().unwrap())
} else {
Err(self.error("length mismatch"))
}
}
fn read_str(&mut self) -> Result<String> {
let len = try!(read_str_len(&mut self.rd));
let mut buf: Vec<u8> = (0..len).map(|_| 0u8).collect();
Ok(try!(read_str_data(&mut self.rd, len, &mut buf[..])).to_string())
}
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T>
where F: FnOnce(&mut Self) -> Result<T> { unimplemented!() }
fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T>
where F: FnMut(&mut Self, usize) -> Result<T> { unimplemented!() }
fn read_enum_variant_arg<T, F>(&mut self, _idx: usize, _f: F) -> Result<T>
where F: FnOnce(&mut Self) -> Result<T> { unimplemented!() }
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T>
where F: FnMut(&mut Self, usize) -> Result<T> { unimplemented!() }
fn read_enum_struct_variant_field<T, F>(&mut self, _name: &str, _idx: usize, _f: F) -> Result<T>
where F: FnOnce(&mut Self) -> Result<T> { unimplemented!() }
fn read_struct<T, F>(&mut self, _name: &str, len: usize, f: F) -> Result<T>
where F: FnOnce(&mut Self) -> Result<T>
{
self.read_tuple(len, f)
}
fn read_struct_field<T, F>(&mut self, _name: &str, _idx: usize, f: F) -> Result<T>
where F: FnOnce(&mut Self) -> Result<T>
{
f(self)
}
fn read_tuple<T, F>(&mut self, len: usize, f: F) -> Result<T>
where F: FnOnce(&mut Self) -> Result<T>
{
let actual = try!(read_array_size(&mut self.rd));
if len == actual as usize {
f(self)
} else {
Err(Error::LengthMismatch(actual))
}
}
fn read_tuple_arg<T, F>(&mut self, _idx: usize, f: F) -> Result<T>
where F: FnOnce(&mut Self) -> Result<T>
{
f(self)
}
fn read_tuple_struct<T, F>(&mut self, _name: &str, _len: usize, _f: F) -> Result<T>
where F: FnOnce(&mut Self) -> Result<T> { unimplemented!() }
fn read_tuple_struct_arg<T, F>(&mut self, _idx: usize, _f: F) -> Result<T>
where F: FnOnce(&mut Self) -> Result<T> { unimplemented!() }
fn read_option<T, F>(&mut self, mut f: F) -> Result<T>
where F: FnMut(&mut Self, bool) -> Result<T>
{
match f(self, true) {
Ok(val) => Ok(val),
Err(Error::TypeMismatch(Marker::Null)) => f(self, false),
Err(err) => Err(err)
}
}
fn read_seq<T, F>(&mut self, f: F) -> Result<T>
where F: FnOnce(&mut Self, usize) -> Result<T>
{
let len = try!(read_array_size(&mut self.rd)) as usize;
f(self, len)
}
fn read_seq_elt<T, F>(&mut self, _idx: usize, f: F) -> Result<T>
where F: FnOnce(&mut Self) -> Result<T>
{
f(self)
}
fn read_map<T, F>(&mut self, f: F) -> Result<T>
where F: FnOnce(&mut Self, usize) -> Result<T>
{
let len = try!(read_map_size(&mut self.rd)) as usize;
f(self, len)
}
fn read_map_elt_key<T, F>(&mut self, _idx: usize, f: F) -> Result<T>
where F: FnOnce(&mut Self) -> Result<T>
{
f(self)
}
fn read_map_elt_val<T, F>(&mut self, _idx: usize, f: F) -> Result<T>
where F: FnOnce(&mut Self) -> Result<T>
{
f(self)
}
fn error(&mut self, err: &str) -> Error {
Error::Uncategorized(err.to_string())
}
}
}