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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
//! # Async Encode/Decode helpers
//!
//! For prior art, see [tokio-codec](https://crates.io/crates/tokio-codec).
//! This borrows many of the ideas that originated there, though with a simpler
//! and `no_std`-compatible approach. No allocation is strictly required by
//! implementers of the [Encode] or [Decode] traits, making them suitable for
//! embedded applications.
//!
//! ## Encoders
//!
//! Encoders are types that implement the [Encode] trait. Consumers of this
//! trait will provide an `Item` to be encoded, along with a buffer into which
//! the resulting bytes should be placed. The `Encode`r may return one of three
//! from this operation:
//!
//! * `EncodeResult::Ok(n)`: The item was successfully encodeded into the
//!   provided buffer and took `n` bytes.
//! * `EncodeResult::Err(e)`: There was an unrecoverable error encoding the
//!   item. Subsequent calls with the same item should return the same error.
//! * `EncodeResult::Overflow(n)`: The item could be encoded, but the encoded
//!   representation would overflow the buffer. If `n > 0`, then a buffer of
//!   length `n` is required to hold the serialized item.
//!
//! Upon an `Overflow` result, the caller should allocate a bigger buffer (if
//! possible), and attempt the operation again. `Encode` implementations may
//! keep a previously encoded `Item` in an internal buffer to make re-attempted
//! encodings cheaper. If this approach is used, the [Encode::reset] method must
//! also be implemented.
//!
//! ## Decoders
//!
//! Decoders implement the [Decode] trait. To decode an `Item`, callers provide
//! the decoder with a buffer containing bytes from the stream. The decoder
//! returns a `usize` indicating that it consumed some number of bytes from the
//! buffer, along with one of three results:
//!
//! * `DecodeResult::Ok(item)`: The `item` was successfully decoded
//! * `DecodeResult::Err(e)`: An error `e` arose when decoding the item. This
//!   does not necessarily invalidate the stream.
//! * `DecodeResult::UnexpectedEnd`: Not enough data to decode yet, caller
//!   should read more and try again with more bytes.
//!
//! Decoders are free to consume bytes in-line with returning `UnexpectedEnd`
//! results and keep a running internal buffer of what's been read so far, or
//! they may opt for consuming the bytes for an `Item` all at once. They should
//! consume bytes in the error case as well so that the caller doesn't provide
//! the same bad data twice.
//!
//! ## Framed
//!
//! The [Framed] type provides a wrapper for `AsyncRead + AsyncWrite` streams
//! that applies an `Encode + Decode` object to create an async `Stream + Sink`
//! of `Item`s. It manages the reads and writes against the underlying stream
//! and the buffers provided to the encode/decode operations. Its error types
//! ([ReadFrameError] and [WriteFrameError]) differentiate between IO errors in
//! the stream (which are usually fatal), and codec errors (which might not be).
//!
//! ## Example
//!
//! ```rust
//! use std::{
//!     io,
//!     str::Utf8Error,
//! };
//!
//! use futures::{
//!     io::Cursor,
//!     prelude::*,
//! };
//!
//! use async_codec::*;
//!
//! struct LineCodec;
//!
//! impl Encode for LineCodec {
//!     type Item = String;
//!     type Error = ();
//!     fn encode(&mut self, item: &String, buf: &mut [u8]) -> EncodeResult<()> {
//!         let needed = item.as_bytes().len() + 1;
//!         if buf.len() < needed {
//!             return EncodeResult::Overflow(needed);
//!         }
//!         buf[..needed - 1].copy_from_slice(item.as_bytes());
//!         buf[needed - 1] = b'\n';
//!         Ok(needed).into()
//!     }
//! }
//!
//! impl Decode for LineCodec {
//!     type Item = String;
//!     type Error = Utf8Error;
//!
//!     fn decode(&mut self, buf: &mut [u8]) -> (usize, DecodeResult<String, Utf8Error>) {
//!         let newline = match buf.iter().position(|b| *b == b'\n') {
//!             Some(idx) => idx,
//!             None => return (0, DecodeResult::UnexpectedEnd),
//!         };
//!         let string_bytes = &buf[..newline];
//!         (
//!             newline + 1,
//!             std::str::from_utf8(string_bytes).map(String::from).into(),
//!         )
//!     }
//! }
//!
//! const SHAKESPEARE: &str = r#"Now is the winter of our discontent
//! Made glorious summer by this sun of York.
//! Some are born great, some achieve greatness
//! And some have greatness thrust upon them.
//! Friends, Romans, countrymen - lend me your ears!
//! I come not to praise Caesar, but to bury him.
//! The evil that men do lives after them
//! The good is oft interred with their bones.
//!                     It is a tale
//! Told by an idiot, full of sound and fury
//! Signifying nothing.
//! Ay me! For aught that I could ever read,
//! Could ever hear by tale or history,
//! The course of true love never did run smooth.
//! I have full cause of weeping, but this heart
//! Shall break into a hundred thousand flaws,
//! Or ere I'll weep.-O Fool, I shall go mad!
//!                     Each your doing,
//! So singular in each particular,
//! Crowns what you are doing in the present deed,
//! That all your acts are queens.
//! "#;
//!
//! #[async_std::main]
//! async fn main() {
//!     let reader = Cursor::new(Vec::from(SHAKESPEARE.as_bytes()));
//!     let mut framed = Framed::new(reader, LineCodec);
//!     let expected = SHAKESPEARE.lines().map(String::from).collect::<Vec<_>>();
//!     let mut actual = vec![];
//!     while let Some(frame) = framed.next().await.transpose().unwrap() {
//!         actual.push(frame);
//!     }
//!     assert_eq!(actual, expected);
//!
//!     let mut actual = vec![0u8; SHAKESPEARE.as_bytes().len()];
//!     let expected = SHAKESPEARE.lines().map(String::from).collect::<Vec<_>>();
//!     let writer = Cursor::new(&mut actual);
//!     let mut framed = Framed::new(writer, LineCodec);
//!     for frame in expected {
//!         framed.send(frame).await.unwrap();
//!     }
//!     assert_eq!(std::str::from_utf8(&actual).unwrap(), SHAKESPEARE);
//! }
//! ```

#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
#![warn(missing_docs)]

#[cfg(feature = "std")]
pub mod framed_std;
#[cfg(all(feature = "std", not(feature = "embrio")))]
pub use crate::framed_std::*;

#[cfg(feature = "embrio")]
pub mod framed_embrio;
#[cfg(all(feature = "embrio", not(feature = "std")))]
pub use crate::framed_embrio::*;

/// The result of an `Encode::encode` call
pub enum EncodeResult<E> {
    /// Item was successfully encoded and took `usize` bytes of the provided
    /// buffer.
    Ok(usize),
    /// There was an error encoding the item.
    Err(E),
    /// The encoded item would overflow the buffer.
    ///
    /// May contain the needed buffer size to successfully hold the encoded
    /// item. The value `0` indicates that the needed buffer size is
    /// unknown.
    Overflow(usize),
}

impl<E> From<Result<usize, E>> for EncodeResult<E> {
    fn from(other: Result<usize, E>) -> Self {
        match other {
            Ok(n) => EncodeResult::Ok(n),
            Err(e) => EncodeResult::Err(e),
        }
    }
}

/// Trait for things that can be encoded to a byte buffer
pub trait Encode {
    /// The item being encoded
    type Item;
    /// The error that may arise from serializing the value
    type Error;

    /// Encode `self` and place the encoded representation in the provided
    /// buffer.
    ///
    /// Returns either a `usize` representing the length of the buffer used, or
    /// an [EncodeResult::Overflow] containing either the minimum required
    /// buffer length, or the error arising from the serialization itself.
    ///
    /// Types implementing `Encode` may employ internal buffering to make
    /// repeated calls to `encode` with the same object cheaper in the event of
    /// an overflow error. If buffering is employed, the internal buffer should
    /// be cleared after the item has been successfully copied into the provided
    /// one.
    fn encode(&mut self, item: &Self::Item, buf: &mut [u8]) -> EncodeResult<Self::Error>;

    /// Signal the encoder that it should discard its internal buffer if it has
    /// one.
    ///
    /// This may be needed if the encoder caches the result of encoding an
    /// `Item` between an `Overflow` result and the `Ok` once the caller has
    /// provided an adequate buffer. Because the caller may not support a
    /// growable buffer, encoders cannot rely on being able to discard thier
    /// buffer when returning `Ok`.
    fn reset(&mut self) {}
}

/// The Result of a `Decode::decode` call
pub enum DecodeResult<T, E> {
    /// Item decoded successfully.
    Ok(T),
    /// A full frame was found, but an error was encountered when decoding it.
    Err(E),
    /// Not enough data to decode a full frame yet, more needs to be read.
    UnexpectedEnd,
}

impl<T, E> From<Result<T, E>> for DecodeResult<T, E> {
    fn from(res: Result<T, E>) -> DecodeResult<T, E> {
        match res {
            Ok(v) => DecodeResult::Ok(v),
            Err(e) => DecodeResult::Err(e),
        }
    }
}

/// Trait for values that can be decoded from a byte buffer
pub trait Decode {
    /// The item being decoded
    type Item;
    /// The error that may arise from a decode operation
    ///
    /// Note that this should *not* be returned in the event of an unexpected
    /// end-of-buffer. Instead, a [DecodeResult::UnexpectedEnd] should be used.
    type Error;

    /// Attempt to decode a value from the buffer
    ///
    /// Returns the number of bytes consumed from the buffer, along with a
    /// [DecodeResult] with either an item, error, or "need more bytes."
    ///
    /// Note that the "bytes consumed" return value should only be non-zero if
    /// either the buffer contains a full frame, or if internal buffering is
    /// employed.
    fn decode(&mut self, buffer: &mut [u8]) -> (usize, DecodeResult<Self::Item, Self::Error>);
}