Skip to content

Instantly share code, notes, and snippets.

@aisk
Created September 30, 2017 14:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aisk/9d2cee45221b0d09107afba1d97be742 to your computer and use it in GitHub Desktop.
Save aisk/9d2cee45221b0d09107afba1d97be742 to your computer and use it in GitHub Desktop.
extern crate bytes;
extern crate futures;
extern crate tokio_io;
extern crate tokio_proto;
extern crate tokio_service;
use std::io;
use std::str;
use bytes::BytesMut;
use futures::{future, Future};
use tokio_io::codec::{Encoder, Decoder};
use tokio_io::codec::Framed;
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_proto::pipeline::ServerProto;
use tokio_proto::TcpServer;
use tokio_service::Service;
pub struct LineCodec;
impl Decoder for LineCodec {
type Item = String;
type Error = io::Error;
fn decode(&mut self, buf: &mut BytesMut) -> io::Result<Option<String>> {
if let Some(i) = buf.iter().position(|&b| b == b'\n') {
let line = buf.split_to(i);
buf.split_to(1);
match str::from_utf8(&line) {
Ok(s) => Ok(Some(s.to_string())),
Err(_) => Err(io::Error::new(io::ErrorKind::Other, "invalid UTF-8")),
}
} else {
return Ok(None);
}
}
}
impl Encoder for LineCodec {
type Item = String;
type Error = io::Error;
fn encode(&mut self, msg: String, buf: &mut BytesMut) -> io::Result<()> {
buf.extend(msg.as_bytes());
buf.extend(b"\n");
return Ok(());
}
}
pub struct LineProto;
impl<T: AsyncRead + AsyncWrite + 'static> ServerProto<T> for LineProto {
type Request = String;
type Response = String;
type Transport = Framed<T, LineCodec>;
type BindTransport = Result<Self::Transport, io::Error>;
fn bind_transport(&self, io: T) -> Self::BindTransport {
return Ok(io.framed(LineCodec));
}
}
pub struct Echo;
impl Service for Echo {
type Request = String;
type Response = String;
type Error = io::Error;
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
fn call(&self, req: Self::Request) -> Self::Future {
Box::new(future::ok(req))
}
}
fn main() {
let addr = "0.0.0.0:12345".parse().unwrap();
let server = TcpServer::new(LineProto, addr);
server.serve(|| Ok(Echo));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment