1
0
mirror of https://github.com/actix/examples synced 2025-01-23 22:34:35 +01:00

123 lines
2.8 KiB
Rust
Raw Normal View History

2018-05-11 14:35:43 -07:00
#![allow(dead_code)]
use byteorder::{BigEndian, ByteOrder};
use bytes::{BufMut, BytesMut};
use serde_json as json;
use std::io;
use tokio_io::codec::{Decoder, Encoder};
/// Client request
#[derive(Serialize, Deserialize, Debug, Message)]
#[serde(tag = "cmd", content = "data")]
pub enum ChatRequest {
/// List rooms
List,
/// Join rooms
Join(String),
/// Send message
Message(String),
/// Ping
Ping,
}
/// Server response
#[derive(Serialize, Deserialize, Debug, Message)]
#[serde(tag = "cmd", content = "data")]
pub enum ChatResponse {
Ping,
/// List of rooms
Rooms(Vec<String>),
/// Joined
Joined(String),
/// Message
Message(String),
}
/// Codec for Client -> Server transport
pub struct ChatCodec;
impl Decoder for ChatCodec {
type Item = ChatRequest;
type Error = io::Error;
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
let size = {
if src.len() < 2 {
return Ok(None);
}
BigEndian::read_u16(src.as_ref()) as usize
};
if src.len() >= size + 2 {
src.split_to(2);
let buf = src.split_to(size);
Ok(Some(json::from_slice::<ChatRequest>(&buf)?))
} else {
Ok(None)
}
}
}
impl Encoder for ChatCodec {
type Item = ChatResponse;
type Error = io::Error;
fn encode(
&mut self, msg: ChatResponse, dst: &mut BytesMut,
) -> Result<(), Self::Error> {
let msg = json::to_string(&msg).unwrap();
let msg_ref: &[u8] = msg.as_ref();
dst.reserve(msg_ref.len() + 2);
2018-05-20 21:03:29 -07:00
dst.put_u16_be(msg_ref.len() as u16);
2018-05-11 14:35:43 -07:00
dst.put(msg_ref);
Ok(())
}
}
/// Codec for Server -> Client transport
pub struct ClientChatCodec;
impl Decoder for ClientChatCodec {
type Item = ChatResponse;
type Error = io::Error;
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
let size = {
if src.len() < 2 {
return Ok(None);
}
BigEndian::read_u16(src.as_ref()) as usize
};
if src.len() >= size + 2 {
src.split_to(2);
let buf = src.split_to(size);
Ok(Some(json::from_slice::<ChatResponse>(&buf)?))
} else {
Ok(None)
}
}
}
impl Encoder for ClientChatCodec {
type Item = ChatRequest;
type Error = io::Error;
fn encode(
&mut self, msg: ChatRequest, dst: &mut BytesMut,
) -> Result<(), Self::Error> {
let msg = json::to_string(&msg).unwrap();
let msg_ref: &[u8] = msg.as_ref();
dst.reserve(msg_ref.len() + 2);
2018-05-20 21:03:29 -07:00
dst.put_u16_be(msg_ref.len() as u16);
2018-05-11 14:35:43 -07:00
dst.put(msg_ref);
Ok(())
}
}