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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
//! Traits for composable encoding and decoding via AsyncRead/AsyncWrites. #![deny(missing_docs)] extern crate futures_core; extern crate futures_io; use std::error::Error; use std::fmt::{self, Display, Formatter}; use futures_core::task::Context; use futures_io::{AsyncWrite, AsyncRead, Error as FutIoErr}; /// The return value for `poll_encode`. pub enum PollEnc<S> { /// The encoder has been run to completion, the last call to `poll_encode` wrote this many bytes. Done(usize), /// Encoding is not done yet, but a non-zero number of bytes was written. Progress(S, usize), /// Encoding can not make progress, because the writer would block. /// The current task is scheduled to be awoken when progress can be made. Pending(S), /// The writer emitted an error. Errored(FutIoErr), } /// A trait for types that asynchronously encode into an `AsyncWrite`. pub trait AsyncEncode where Self: Sized { /// Call `writer.poll_write` once with encoded data, propagating any `Err` and /// `Pending`, and returning how many bytes were written. /// /// This consumes ownership of the encoder. If encoding did not terminate, the return value /// contains a new encoder that will resume at the correct point. /// /// If `writer.poll_write` returns `Ok(Ready(0))` even though the value has not been fully /// encoded, this must return an error of kind `WriteZero`. fn poll_encode<W: AsyncWrite>(self, cx: &mut Context, writer: &mut W) -> PollEnc<Self>; } /// An `AsyncEncode` that can precompute how many bytes of encoded data it produces. pub trait AsyncEncodeLen: AsyncEncode { /// Return the exact number of bytes this will still write. fn remaining_bytes(&self) -> usize; } /// The return value for `poll_decode`. pub enum PollDec<T, S, E> { /// The decoder has run to completion, yielding an item of type `T`. The second value is the /// number of bytes that were read in the last call to `poll_read`. Done(T, usize), /// Decoding is not done yet, but a non-zero number of bytes was read. Progress(S, usize), /// Decoding can not make progress, because the reader would block. /// /// The current task is scheduled to be awoken when progress can be made. Pending(S), /// An error occured during encoding. Errored(DecodeError<E>), } /// A trait for types can be asynchronously decoded from an `AsyncRead`. pub trait AsyncDecode where Self: Sized { /// The type of the value to decode. type Item; /// An error indicating how decoding can fail. type Error; /// Call `reader.poll_read` exactly once, propgating any `Err` and `Pending`, and return how /// many bytes have been read, as well as the decoded value, once decoding is done. /// /// This consumes ownership of the decoder. If decoding did not terminate, the return value /// contains a new decoder that will resume at the correct point. /// /// If `reader.poll_read` returns `Ok(Ready(0))` even though the value has not been fully /// decoded, this must return an error of kind `UnexpectedEof`. fn poll_decode<R: AsyncRead>(self, cx: &mut Context, reader: &mut R) -> PollDec<Self::Item, Self, Self::Error>; } /// An error that occured during decoding. #[derive(Debug)] pub enum DecodeError<E> { /// An error propagated from the underlying reader. ReaderError(FutIoErr), /// An error describing why the read data could not be decoded into a value. DataError(E), } impl<E: Display> Display for DecodeError<E> { fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { match *self { DecodeError::ReaderError(ref err) => write!(f, "Decode reader error: {}", err), DecodeError::DataError(ref err) => write!(f, "Decode data error: {}", err), } } } impl<E: Error> Error for DecodeError<E> { fn description(&self) -> &str { match *self { DecodeError::ReaderError(ref err) => err.description(), DecodeError::DataError(ref err) => err.description(), } } fn cause(&self) -> Option<&Error> { match *self { DecodeError::ReaderError(ref err) => Some(err), DecodeError::DataError(ref err) => Some(err), } } } impl<E> From<FutIoErr> for DecodeError<E> { fn from(err: FutIoErr) -> DecodeError<E> { DecodeError::ReaderError(err) } }