Reintroduce "decoder" and "encoder" for Decode and Encode, and merge the

traits into `Codec`

A previous commit refactored such that `Encode` and `Decode` are
implemented directly on the types being encoded or decoded. This was
thought to be less expressive but more convenient than having a separate
notion of a (stateful) encoder or decoder.

However, there are certain situations where the approach is just too
limiting: you're required to implemented `Decode` and `Encode` for types
you don't "own" and can't newtype.

This commit moves back to a setup where `Self` represents the
encoder/decoder state; it also merges the two traits into a single
`Codec` trait, since they are currently always used together.
This commit is contained in:
Aaron Turon
2016-11-15 08:28:26 -08:00
parent f6241b6330
commit c353de13fc
3 changed files with 120 additions and 175 deletions
+6 -10
View File
@@ -42,7 +42,7 @@ mod split;
mod window;
mod write_all;
pub use self::copy::{copy, Copy};
pub use self::frame::{EasyBuf, EasyBufMut, FramedRead, FramedWrite, Framed, Decode, Encode};
pub use self::frame::{EasyBuf, EasyBufMut, FramedRead, FramedWrite, Framed, Codec};
pub use self::flush::{flush, Flush};
pub use self::read_exact::{read_exact, ReadExact};
pub use self::read_to_end::{read_to_end, ReadToEnd};
@@ -113,13 +113,9 @@ pub trait Io: io::Read + io::Write {
///
/// Raw I/O objects work with byte sequences, but higher-level code usually
/// wants to batch these into meaningful chunks, called "frames". This
/// method layers framing on top of an I/O object, by using the `Encode` and
/// `Decode` traits:
///
/// - `Encode` interprets frames we want to send into bytes;
/// - `Decode` interprets incoming bytes into a stream of frames.
///
/// Note that the incoming and outgoing frame types may be distinct.
/// method layers framing on top of an I/O object, by using the `Codec`
/// traits to handle encoding and decoding of messages frames. Note that
/// the incoming and outgoing frame types may be distinct.
///
/// This function returns a *single* object that is both `Stream` and
/// `Sink`; grouping this into a single object is often useful for layering
@@ -129,10 +125,10 @@ pub trait Io: io::Read + io::Write {
/// If you want to work more directly with the streams and sink, consider
/// calling `split` on the `Framed` returned by this method, which will
/// break them into separate objects, allowing them to interact more easily.
fn framed<D: Decode, E: Encode>(self) -> Framed<Self, D, E>
fn framed<C: Codec>(self, codec: C) -> Framed<Self, C>
where Self: Sized,
{
frame::framed(self)
frame::framed(self, codec)
}
/// Helper method for splitting this read/write object into two halves.