Skip to content

Instantly share code, notes, and snippets.

@robo-corg
Created April 15, 2017 04:00
Show Gist options
  • Save robo-corg/66bb08dcb8a8f86d3ac1b2d0cf205649 to your computer and use it in GitHub Desktop.
Save robo-corg/66bb08dcb8a8f86d3ac1b2d0cf205649 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::Result;
use std::error::Error;
use bytes::{BytesMut, BufMut};
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_io::codec::{Framed, Encoder, Decoder};
use tokio_proto::pipeline::ServerProto;
use tokio_service::Service;
use futures::{future, Future, BoxFuture};
use tokio_proto::TcpServer;
#[derive(Debug)]
pub enum MsgError {
InvalidHeader,
}
impl std::error::Error for MsgError {
fn description(&self) -> &str {
match self {
&MsgError::InvalidHeader => "Invalid Header"
}
}
}
impl std::fmt::Display for MsgError {
fn fmt(&self, formatter : &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
write!(formatter, "{}", self.description())
}
}
impl std::convert::Into<std::io::Error> for MsgError {
fn into(self) -> std::io::Error {
return std::io::Error::new(std::io::ErrorKind::InvalidData, self);
}
}
pub enum Message {
Connect,
Welcome
}
pub struct VoxSrvCodec;
impl Decoder for VoxSrvCodec {
type Item = Message;
type Error = std::io::Error;
fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Message>> {
if buf.len() < 1 {
return Ok(None);
}
let header_type : u8 = *buf.get(0).unwrap();
match header_type {
1 => Ok(Some(Message::Connect)),
2 => Ok(Some(Message::Welcome)),
_ => Err(MsgError::InvalidHeader.into())
}
}
}
impl Encoder for VoxSrvCodec {
type Item = Message;
type Error = std::io::Error;
fn encode(&mut self, msg: Message, buf: &mut BytesMut) -> Result<()> {
let header_type : u8 = match msg {
Message::Connect => 1,
Message::Welcome => 2,
};
buf.extend([header_type].iter());
Ok(())
}
}
pub struct WizSrvProto;
impl<T: AsyncRead + AsyncWrite + 'static> ServerProto<T> for WizSrvProto {
/// For this protocol style, `Request` matches the codec `In` type
type Request = Message;
/// For this protocol style, `Response` matches the coded `Out` type
type Response = Message;
/// A bit of boilerplate to hook in the codec:
type Transport = Framed<T, VoxSrvCodec>;
type BindTransport = std::result::Result<Self::Transport, std::io::Error>;
fn bind_transport(&self, io: T) -> Self::BindTransport {
Ok(io.framed(VoxSrvCodec))
}
}
pub struct WizSrv;
impl Service for WizSrv {
type Request = Message;
type Response = Message;
type Error = std::io::Error;
type Future = BoxFuture<Self::Response, Self::Error>;
fn call(&self, req: Self::Request) -> Self::Future {
// Just return the request, doubled
future::ok(Message::Welcome).boxed()
}
}
fn serve(addr_raw : &str) {
//let addr = addr_raw.parse().unwrap();
let addr = "0.0.0.0:12345".parse().unwrap();
// The builder requires a protocol and an address
let server = TcpServer::new(WizSrvProto, addr);
// error[E0277]: the trait bound `WizSrvProto: tokio_proto::BindServer<_, tokio_core::net::tcp::TcpStream>` is not satisfied
// --> src/wiz_srv/src/lib.rs:120:18
// |
// 120 | let server = TcpServer::new(WizSrvProto, addr);
// | ^^^^^^^^^^^^^^ the trait `tokio_proto::BindServer<_, tokio_core::net::tcp::TcpStream>` is not implemented for `WizSrvProto`
// |
// = note: required by `<tokio_proto::TcpServer<Kind, P>>::new`
// We provide a way to *instantiate* the service for each new
// connection; here, we just immediately return a new instance.
//server.serve(|| Ok(WizSrv));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment