async_codec/
lib.rs

1//! # Async Encode/Decode helpers
2//!
3//! For prior art, see [tokio-codec](https://crates.io/crates/tokio-codec).
4//! This borrows many of the ideas that originated there, though with a simpler
5//! and `no_std`-compatible approach. No allocation is strictly required by
6//! implementers of the [Encode] or [Decode] traits, making them suitable for
7//! embedded applications.
8//!
9//! ## Encoders
10//!
11//! Encoders are types that implement the [Encode] trait. Consumers of this
12//! trait will provide an `Item` to be encoded, along with a buffer into which
13//! the resulting bytes should be placed. The `Encode`r may return one of three
14//! from this operation:
15//!
16//! * `EncodeResult::Ok(n)`: The item was successfully encodeded into the
17//!   provided buffer and took `n` bytes.
18//! * `EncodeResult::Err(e)`: There was an unrecoverable error encoding the
19//!   item. Subsequent calls with the same item should return the same error.
20//! * `EncodeResult::Overflow(n)`: The item could be encoded, but the encoded
21//!   representation would overflow the buffer. If `n > 0`, then a buffer of
22//!   length `n` is required to hold the serialized item.
23//!
24//! Upon an `Overflow` result, the caller should allocate a bigger buffer (if
25//! possible), and attempt the operation again. `Encode` implementations may
26//! keep a previously encoded `Item` in an internal buffer to make re-attempted
27//! encodings cheaper. If this approach is used, the [Encode::reset] method must
28//! also be implemented.
29//!
30//! ## Decoders
31//!
32//! Decoders implement the [Decode] trait. To decode an `Item`, callers provide
33//! the decoder with a buffer containing bytes from the stream. The decoder
34//! returns a `usize` indicating that it consumed some number of bytes from the
35//! buffer, along with one of three results:
36//!
37//! * `DecodeResult::Ok(item)`: The `item` was successfully decoded
38//! * `DecodeResult::Err(e)`: An error `e` arose when decoding the item. This
39//!   does not necessarily invalidate the stream.
40//! * `DecodeResult::UnexpectedEnd`: Not enough data to decode yet, caller
41//!   should read more and try again with more bytes.
42//!
43//! Decoders are free to consume bytes in-line with returning `UnexpectedEnd`
44//! results and keep a running internal buffer of what's been read so far, or
45//! they may opt for consuming the bytes for an `Item` all at once. They should
46//! consume bytes in the error case as well so that the caller doesn't provide
47//! the same bad data twice.
48//!
49//! ## Framed
50//!
51//! The [Framed] type provides a wrapper for `AsyncRead + AsyncWrite` streams
52//! that applies an `Encode + Decode` object to create an async `Stream + Sink`
53//! of `Item`s. It manages the reads and writes against the underlying stream
54//! and the buffers provided to the encode/decode operations. Its error types
55//! ([ReadFrameError] and [WriteFrameError]) differentiate between IO errors in
56//! the stream (which are usually fatal), and codec errors (which might not be).
57//!
58//! ## Example
59//!
60//! ```rust
61//! use std::{
62//!     io,
63//!     str::Utf8Error,
64//! };
65//!
66//! use futures::{
67//!     io::Cursor,
68//!     prelude::*,
69//! };
70//!
71//! use async_codec::*;
72//!
73//! struct LineCodec;
74//!
75//! impl Encode for LineCodec {
76//!     type Item = String;
77//!     type Error = ();
78//!     fn encode(&mut self, item: &String, buf: &mut [u8]) -> EncodeResult<()> {
79//!         let needed = item.as_bytes().len() + 1;
80//!         if buf.len() < needed {
81//!             return EncodeResult::Overflow(needed);
82//!         }
83//!         buf[..needed - 1].copy_from_slice(item.as_bytes());
84//!         buf[needed - 1] = b'\n';
85//!         Ok(needed).into()
86//!     }
87//! }
88//!
89//! impl Decode for LineCodec {
90//!     type Item = String;
91//!     type Error = Utf8Error;
92//!
93//!     fn decode(&mut self, buf: &mut [u8]) -> (usize, DecodeResult<String, Utf8Error>) {
94//!         let newline = match buf.iter().position(|b| *b == b'\n') {
95//!             Some(idx) => idx,
96//!             None => return (0, DecodeResult::UnexpectedEnd),
97//!         };
98//!         let string_bytes = &buf[..newline];
99//!         (
100//!             newline + 1,
101//!             std::str::from_utf8(string_bytes).map(String::from).into(),
102//!         )
103//!     }
104//! }
105//!
106//! const SHAKESPEARE: &str = r#"Now is the winter of our discontent
107//! Made glorious summer by this sun of York.
108//! Some are born great, some achieve greatness
109//! And some have greatness thrust upon them.
110//! Friends, Romans, countrymen - lend me your ears!
111//! I come not to praise Caesar, but to bury him.
112//! The evil that men do lives after them
113//! The good is oft interred with their bones.
114//!                     It is a tale
115//! Told by an idiot, full of sound and fury
116//! Signifying nothing.
117//! Ay me! For aught that I could ever read,
118//! Could ever hear by tale or history,
119//! The course of true love never did run smooth.
120//! I have full cause of weeping, but this heart
121//! Shall break into a hundred thousand flaws,
122//! Or ere I'll weep.-O Fool, I shall go mad!
123//!                     Each your doing,
124//! So singular in each particular,
125//! Crowns what you are doing in the present deed,
126//! That all your acts are queens.
127//! "#;
128//!
129//! #[async_std::main]
130//! async fn main() {
131//!     let reader = Cursor::new(Vec::from(SHAKESPEARE.as_bytes()));
132//!     let mut framed = Framed::new(reader, LineCodec);
133//!     let expected = SHAKESPEARE.lines().map(String::from).collect::<Vec<_>>();
134//!     let mut actual = vec![];
135//!     while let Some(frame) = framed.next().await.transpose().unwrap() {
136//!         actual.push(frame);
137//!     }
138//!     assert_eq!(actual, expected);
139//!
140//!     let mut actual = vec![0u8; SHAKESPEARE.as_bytes().len()];
141//!     let expected = SHAKESPEARE.lines().map(String::from).collect::<Vec<_>>();
142//!     let writer = Cursor::new(&mut actual);
143//!     let mut framed = Framed::new(writer, LineCodec);
144//!     for frame in expected {
145//!         framed.send(frame).await.unwrap();
146//!     }
147//!     assert_eq!(std::str::from_utf8(&actual).unwrap(), SHAKESPEARE);
148//! }
149//! ```
150
151#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
152#![warn(missing_docs)]
153
154#[cfg(feature = "std")]
155pub mod framed_std;
156#[cfg(all(feature = "std", not(feature = "embrio")))]
157pub use crate::framed_std::*;
158
159#[cfg(feature = "embrio")]
160pub mod framed_embrio;
161#[cfg(all(feature = "embrio", not(feature = "std")))]
162pub use crate::framed_embrio::*;
163
164/// The result of an `Encode::encode` call
165pub enum EncodeResult<E> {
166    /// Item was successfully encoded and took `usize` bytes of the provided
167    /// buffer.
168    Ok(usize),
169    /// There was an error encoding the item.
170    Err(E),
171    /// The encoded item would overflow the buffer.
172    ///
173    /// May contain the needed buffer size to successfully hold the encoded
174    /// item. The value `0` indicates that the needed buffer size is
175    /// unknown.
176    Overflow(usize),
177}
178
179impl<E> From<Result<usize, E>> for EncodeResult<E> {
180    fn from(other: Result<usize, E>) -> Self {
181        match other {
182            Ok(n) => EncodeResult::Ok(n),
183            Err(e) => EncodeResult::Err(e),
184        }
185    }
186}
187
188/// Trait for things that can be encoded to a byte buffer
189pub trait Encode {
190    /// The item being encoded
191    type Item;
192    /// The error that may arise from serializing the value
193    type Error;
194
195    /// Encode `self` and place the encoded representation in the provided
196    /// buffer.
197    ///
198    /// Returns either a `usize` representing the length of the buffer used, or
199    /// an [EncodeResult::Overflow] containing either the minimum required
200    /// buffer length, or the error arising from the serialization itself.
201    ///
202    /// Types implementing `Encode` may employ internal buffering to make
203    /// repeated calls to `encode` with the same object cheaper in the event of
204    /// an overflow error. If buffering is employed, the internal buffer should
205    /// be cleared after the item has been successfully copied into the provided
206    /// one.
207    fn encode(&mut self, item: &Self::Item, buf: &mut [u8]) -> EncodeResult<Self::Error>;
208
209    /// Signal the encoder that it should discard its internal buffer if it has
210    /// one.
211    ///
212    /// This may be needed if the encoder caches the result of encoding an
213    /// `Item` between an `Overflow` result and the `Ok` once the caller has
214    /// provided an adequate buffer. Because the caller may not support a
215    /// growable buffer, encoders cannot rely on being able to discard thier
216    /// buffer when returning `Ok`.
217    fn reset(&mut self) {}
218}
219
220/// The Result of a `Decode::decode` call
221pub enum DecodeResult<T, E> {
222    /// Item decoded successfully.
223    Ok(T),
224    /// A full frame was found, but an error was encountered when decoding it.
225    Err(E),
226    /// Not enough data to decode a full frame yet, more needs to be read.
227    UnexpectedEnd,
228}
229
230impl<T, E> From<Result<T, E>> for DecodeResult<T, E> {
231    fn from(res: Result<T, E>) -> DecodeResult<T, E> {
232        match res {
233            Ok(v) => DecodeResult::Ok(v),
234            Err(e) => DecodeResult::Err(e),
235        }
236    }
237}
238
239/// Trait for values that can be decoded from a byte buffer
240pub trait Decode {
241    /// The item being decoded
242    type Item;
243    /// The error that may arise from a decode operation
244    ///
245    /// Note that this should *not* be returned in the event of an unexpected
246    /// end-of-buffer. Instead, a [DecodeResult::UnexpectedEnd] should be used.
247    type Error;
248
249    /// Attempt to decode a value from the buffer
250    ///
251    /// Returns the number of bytes consumed from the buffer, along with a
252    /// [DecodeResult] with either an item, error, or "need more bytes."
253    ///
254    /// Note that the "bytes consumed" return value should only be non-zero if
255    /// either the buffer contains a full frame, or if internal buffering is
256    /// employed.
257    fn decode(&mut self, buffer: &mut [u8]) -> (usize, DecodeResult<Self::Item, Self::Error>);
258}