Updated Tokio protocol code.

This commit is contained in:
Aaron Weiss 2017-05-26 14:09:09 +02:00
parent 6a0f2a184f
commit 9a2222d802
No known key found for this signature in database
GPG key ID: 0237035D9BF03AE2
4 changed files with 36 additions and 21 deletions

View file

@ -17,11 +17,13 @@ ctcp = []
nochanlists = []
[dependencies]
bytes = "0.4"
encoding = "0.2"
futures = "0.1"
native-tls = "0.1"
rustc-serialize = "0.3"
time = "0.1"
tokio-core = "0.1"
tokio-io = "0.1"
tokio-service = "0.1"
tokio-tls = "0.1"

View file

@ -2,11 +2,13 @@
#![warn(missing_docs)]
extern crate bytes;
extern crate encoding;
extern crate futures;
extern crate native_tls;
extern crate rustc_serialize;
extern crate time;
extern crate tokio_io;
extern crate tokio_core;
extern crate tokio_service;
extern crate tokio_tls;

View file

@ -1,9 +1,10 @@
//! Implementation of IRC codec for Tokio.
use std::io;
use bytes::BytesMut;
use tokio_io::codec::{Decoder, Encoder};
use proto::line::LineCodec;
use proto::message::Message;
use tokio_core::io::{Codec, EasyBuf};
/// An IRC codec built around an inner codec.
pub struct IrcCodec {
@ -17,19 +18,25 @@ impl IrcCodec {
}
}
impl Codec for IrcCodec {
type In = Message;
type Out = Message;
impl Decoder for IrcCodec {
type Item = Message;
type Error = io::Error;
fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<Message>> {
self.inner.decode(buf).and_then(|res| res.map_or(Ok(None), |msg| {
fn decode(&mut self, src: &mut BytesMut) -> io::Result<Option<Message>> {
self.inner.decode(src).and_then(|res| res.map_or(Ok(None), |msg| {
msg.parse::<Message>().map(|msg| Some(msg)).map_err(|err| {
io::Error::new(io::ErrorKind::InvalidInput, err)
})
}))
}
}
fn encode(&mut self, msg: Message, buf: &mut Vec<u8>) -> io::Result<()> {
self.inner.encode(msg.to_string(), buf)
impl Encoder for IrcCodec {
type Item = Message;
type Error = io::Error;
fn encode(&mut self, msg: Message, dst: &mut BytesMut) -> io::Result<()> {
self.inner.encode(msg.to_string(), dst)
}
}

View file

@ -1,10 +1,10 @@
//! Implementation of line-delimiting codec for Tokio.
use std::io;
use std::io::prelude::*;
use bytes::{BufMut, BytesMut};
use encoding::{DecoderTrap, EncoderTrap, EncodingRef};
use encoding::label::encoding_from_whatwg_label;
use tokio_core::io::{Codec, EasyBuf};
use tokio_io::codec::{Decoder, Encoder};
/// A line-based codec parameterized by an encoding.
pub struct LineCodec {
@ -23,17 +23,17 @@ impl LineCodec {
}
}
impl Codec for LineCodec {
type In = String;
type Out = String;
impl Decoder for LineCodec {
type Item = String;
type Error = io::Error;
fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<String>> {
if let Some(n) = buf.as_ref().iter().position(|b| *b == b'\n') {
fn decode(&mut self, src: &mut BytesMut) -> io::Result<Option<String>> {
if let Some(n) = src.as_ref().iter().position(|b| *b == b'\n') {
// Remove the next frame from the buffer.
let line = buf.drain_to(n);
let line = src.split_to(n + 1);
// Remove the new-line from the buffer.
buf.drain_to(1);
src.split_to(1);
// Decode the line using the codec's encoding.
match self.encoding.decode(line.as_ref(), DecoderTrap::Replace) {
@ -47,8 +47,13 @@ impl Codec for LineCodec {
Ok(None)
}
}
}
fn encode(&mut self, msg: String, buf: &mut Vec<u8>) -> io::Result<()> {
impl Encoder for LineCodec {
type Item = String;
type Error = io::Error;
fn encode(&mut self, msg: String, dst: &mut BytesMut) -> io::Result<()> {
// Encode the message using the codec's encoding.
let data = try!(self.encoding.encode(&msg, EncoderTrap::Replace).map_err(|data| {
io::Error::new(
@ -58,9 +63,8 @@ impl Codec for LineCodec {
}));
// Write the encoded message to the output buffer.
try!(buf.write_all(&data));
dst.put(&data);
// Flush the output buffer.
buf.flush()
Ok(())
}
}