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
+13 -12
View File
@@ -6,29 +6,30 @@ use std::io;
use std::net::Shutdown;
use futures::{Future, Stream, Sink};
use tokio_core::io::{write_all, read, Encode, Decode, EasyBuf, Io};
use tokio_core::io::{write_all, read, Codec, EasyBuf, Io};
use tokio_core::net::{TcpListener, TcpStream};
use tokio_core::reactor::Core;
pub struct Line(EasyBuf);
pub struct LineCodec;
impl Decode for Line {
fn decode(buf: &mut EasyBuf) -> Result<Option<Line>, io::Error> {
impl Codec for LineCodec {
type In = EasyBuf;
type Out = EasyBuf;
fn decode(&mut self, buf: &mut EasyBuf) -> Result<Option<EasyBuf>, io::Error> {
match buf.as_slice().iter().position(|&b| b == b'\n') {
Some(i) => Ok(Some(Line(buf.drain_to(i + 1).into()))),
Some(i) => Ok(Some(buf.drain_to(i + 1).into())),
None => Ok(None),
}
}
fn done(buf: &mut EasyBuf) -> io::Result<Line> {
fn decode_eof(&mut self, buf: &mut EasyBuf) -> io::Result<EasyBuf> {
let amt = buf.len();
Ok(Line(buf.drain_to(amt)))
Ok(buf.drain_to(amt))
}
}
impl Encode for Line {
fn encode(self, into: &mut Vec<u8>) {
into.extend_from_slice(self.0.as_slice());
fn encode(&mut self, item: EasyBuf, into: &mut Vec<u8>) {
into.extend_from_slice(item.as_slice());
}
}
@@ -42,7 +43,7 @@ fn echo() {
let listener = TcpListener::bind(&"127.0.0.1:0".parse().unwrap(), &handle).unwrap();
let addr = listener.local_addr().unwrap();
let srv = listener.incoming().for_each(move |(socket, _)| {
let (stream, sink) = socket.framed::<Line, Line>().split();
let (stream, sink) = socket.framed(LineCodec).split();
handle.spawn(sink.send_all(stream).map(|_| ()).map_err(|_| ()));
Ok(())
});