use std::{io, str};
use tokio_io::codec::{Encoder, Decoder};
use bytes::{BytesMut, BufMut};
#[derive(Default)]
pub struct LineCodec;
impl Decoder for LineCodec {
type Item = BytesMut;
type Error = io::Error;
fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
trace!("LineCodec::decode(): {}", str::from_utf8(buf).unwrap_or("utf8 decode failed"));
match buf.iter().position(|&b| b == b'\n') {
Some(i) => {
let line = buf.split_to(i + 1);
debug!("Decoded line: {}", str::from_utf8(&line).unwrap_or("utf8 decode failed"));
Ok(Some(line))
},
None => Ok(None),
}
}
fn decode_eof(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
if buf.len() == 0 {
Ok(None)
} else {
let amt = buf.len();
let line = buf.split_to(amt);
debug!("Decoded line at EOF: {}", str::from_utf8(&line).unwrap_or("utf8 decode failed"));
Ok(Some(line))
}
}
}
impl Encoder for LineCodec {
type Item = Box<[u8]>;
type Error = io::Error;
fn encode(&mut self, item: Self::Item, into: &mut BytesMut) -> Result<(), Self::Error> {
into.reserve(item.len());
into.put(&item[..]);
debug!("Encoded line: {}", str::from_utf8(&item).unwrap_or("utf8 decode failed"));
Ok(())
}
}