pbcodec 0.0.8

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

use {Encode, Error, Message};
use future::util;
use traits::Field;
use types::Embedded;
use wire::types::{LengthDelimited, Varint};
use super::EncodeLengthDelimited;

pub struct EncodeMessage<W, T>
where
    W: Write,
    T: Message,
    T::Base: Encode<W>,
{
    future: <T::Base as Encode<W>>::Future,
}
impl<W: Write, T: Message> EncodeMessage<W, T>
where
    T::Base: Encode<W>,
{
    pub fn new(writer: W, message: T) -> Self {
        let future = message.into_base().encode(writer);
        EncodeMessage { future }
    }
}
impl<W: Write, T: Message> Future for EncodeMessage<W, T>
where
    T::Base: Encode<W>,
{
    type Item = W;
    type Error = Error<W>;
    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        track!(self.future.poll())
    }
}

pub struct EncodeEmbeddedMessage<W, T>
where
    W: Write,
    T: Message,
    T::Base: Encode<W>,
{
    future: EncodeLengthDelimited<W, T::Base>,
}
impl<W, T> Future for EncodeEmbeddedMessage<W, T>
where
    W: Write,
    T: Message,
    T::Base: Encode<W>,
{
    type Item = W;
    type Error = Error<W>;
    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        track!(self.future.poll())
    }
}
impl<W: Write, T: Message> Encode<W> for Embedded<T>
where
    T::Base: Encode<W>,
{
    type Future = EncodeEmbeddedMessage<W, T>;
    fn encode(self, writer: W) -> Self::Future {
        let future = LengthDelimited(self.0).encode(writer);
        EncodeEmbeddedMessage { future }
    }
    fn encoded_size(&self) -> u64 {
        let size = self.0.encoded_size();
        Encode::<W>::encoded_size(&Varint(size)) + size
    }
}

macro_rules! define_and_impl_tuple_encoder {
    ($name:ident, $phase:ident, [$(($prev:ident, $num:tt, $param:ident)),*], $last_param:ident) => {
        #[allow(dead_code)]
        pub struct $name<W, A, $($param),*>
        where
            W: Write,
            A: Encode<W>,
            $($param: Encode<W>),*
        {
            phase: util::$phase<A::Future, $($param::Future),*>,
            values: (A, $($param),*),
        }
        impl<W, A, $($param),*> Future for $name<W, A, $($param),*>
        where
            W: Write,
            A: Encode<W> + Field,
            $($param: Encode<W> + Field),*
        {
            type Item = W;
            type Error = Error<W>;
            #[allow(unused_variables, unreachable_code)]
            fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
                while let Async::Ready(phase) = track!(self.phase.poll())? {
                    let next = match phase {
                        $(util::$phase::$prev(w) => {
                            let v = mem::replace(&mut self.values.$num, Default::default());
                            util::$phase::$param(v.encode(w))
                        })*
                            util::$phase::$last_param(w) => return Ok(Async::Ready(w)),
                    };
                    self.phase = next;
                }
                Ok(Async::NotReady)
            }
        }
        impl<W, A, $($param),*> Encode<W> for (A, $($param),*)
        where
            W: Write,
            A: Encode<W> + Field,
            $($param: Encode<W> + Field),*
        {
            type Future = $name<W, A, $($param),*>;
            fn encode(mut self, writer: W) -> Self::Future {
                let v = mem::replace(&mut self.0, Default::default());
                let phase = util::$phase::A(v.encode(writer));
                $name {
                    phase,
                    values: self,
                }
            }
            fn encoded_size(&self) -> u64 {
                self.0.encoded_size() $(+ self.$num.encoded_size())*
            }
        }
    }
}
define_and_impl_tuple_encoder!(EncodeTupleMessage1, Phase1, [], A);
define_and_impl_tuple_encoder!(EncodeTupleMessage2, Phase2, [(A, 1, B)], B);
define_and_impl_tuple_encoder!(EncodeTupleMessage3, Phase3, [(A, 1, B), (B, 2, C)], C);
define_and_impl_tuple_encoder!(
    EncodeTupleMessage4,
    Phase4,
    [(A, 1, B), (B, 2, C), (C, 3, D)],
    D
);
define_and_impl_tuple_encoder!(
    EncodeTupleMessage5,
    Phase5,
    [(A, 1, B), (B, 2, C), (C, 3, D), (D, 4, E)],
    E
);
define_and_impl_tuple_encoder!(
    EncodeTupleMessage6,
    Phase6,
    [(A, 1, B), (B, 2, C), (C, 3, D), (D, 4, E), (E, 5, F)],
    F
);
define_and_impl_tuple_encoder!(
    EncodeTupleMessage7,
    Phase7,
    [
        (A, 1, B),
        (B, 2, C),
        (C, 3, D),
        (D, 4, E),
        (E, 5, F),
        (F, 6, G) //,
    ],
    G
);
define_and_impl_tuple_encoder!(
    EncodeTupleMessage8,
    Phase8,
    [
        (A, 1, B),
        (B, 2, C),
        (C, 3, D),
        (D, 4, E),
        (E, 5, F),
        (F, 6, G),
        (G, 7, H) //,
    ],
    H
);