pbcodec 0.0.8

An asynchronous encoder/decoder for Protocol Buffers
Documentation
use std::io::Read;
use futures::{Future, Poll};

use Error;
use fields;
use traits::{DecodeField, SingularField};
use variants;
use wire::WireType;

macro_rules! define_and_impl_decode_oneof {
    ($oneof:ident, $decoder:ident, $variant:ident, $($param:ident),*) => {
        #[derive(Debug)]
        pub enum $decoder<R, $($param),*>
        where
            R: Read,
            $($param: DecodeField<R>),*
        {
            $($param($param::Future)),*
        }

        impl<R, $($param),*> Future for $decoder<R, $($param),*>
        where
            R: Read,
            $($param: DecodeField<R> + SingularField),*
        {
            type Item = (R, fields::$oneof<$($param),*>);
            type Error = Error<R>;
            fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
                Ok(match *self {
                    $($decoder::$param(ref mut f) => {
                        track!(f.poll())?.map(|(r, v)| {
                            (r, From::from(Some(variants::$variant::$param(v))))
                        })
                    }),*
                })
            }
        }

        impl<R, $($param),*> DecodeField<R> for fields::$oneof<$($param),*>
        where
            R: Read,
            $($param: DecodeField<R> + SingularField),*
        {
            type Future = $decoder<R, $($param),*>;
            fn is_target(tag: u32) -> bool {
                $($param::is_target(tag))||*
            }
            fn decode_field(
                self,
                reader: R,
                tag: u32,
                wire_type: WireType,
            ) -> Result<Self::Future, Error<R>> {
                if false {
                    unreachable!()
                }
                $(else if $param::is_target(tag) {
                    let f = track!($param::default().decode_field(reader, tag, wire_type))?;
                    Ok($decoder::$param(f))
                })*
                else {
                    unreachable!()
                }
            }
        }
    }
}

define_and_impl_decode_oneof!(Oneof1, DecodeOneof1, Variant1, A);
define_and_impl_decode_oneof!(Oneof2, DecodeOneof2, Variant2, A, B);
define_and_impl_decode_oneof!(Oneof3, DecodeOneof3, Variant3, A, B, C);
define_and_impl_decode_oneof!(Oneof4, DecodeOneof4, Variant4, A, B, C, D);
define_and_impl_decode_oneof!(Oneof5, DecodeOneof5, Variant5, A, B, C, D, E);
define_and_impl_decode_oneof!(Oneof6, DecodeOneof6, Variant6, A, B, C, D, E, F);
define_and_impl_decode_oneof!(Oneof7, DecodeOneof7, Variant7, A, B, C, D, E, F, G);
define_and_impl_decode_oneof!(Oneof8, DecodeOneof8, Variant8, A, B, C, D, E, F, G, H);