From c48673c390e2522cde7c352d29adad72da31c032 Mon Sep 17 00:00:00 2001 From: Titouan Rigoudy Date: Sat, 24 Nov 2018 20:47:23 +0000 Subject: [PATCH] Introduce ProtoDecoder instead of extending Buf trait. --- src/proto/base_codec.rs | 340 +++++++++++++++++++---------------- src/proto/handler.rs | 12 +- src/proto/mod.rs | 2 +- src/proto/peer/message.rs | 31 ++-- src/proto/server/request.rs | 117 ++++++------ src/proto/server/response.rs | 277 ++++++++++++++-------------- src/proto/transport.rs | 15 +- src/proto/user.rs | 10 +- 8 files changed, 414 insertions(+), 390 deletions(-) diff --git a/src/proto/base_codec.rs b/src/proto/base_codec.rs index 1c57755..739f062 100644 --- a/src/proto/base_codec.rs +++ b/src/proto/base_codec.rs @@ -56,41 +56,89 @@ fn invalid_data_error(type_name: &str, value: T) -> io::Error { ) } -// A few helper methods for implementing Decode for basic types. -trait BootstrapDecode: Buf { - // Asserts that the buffer contains at least `n` more bytes from which to - // read a value of the given type. - // Returns Ok(()) if there are that many bytes, an error otherwise. - fn expect_remaining(&self, type_name: &str, n: usize) -> io::Result<()>; +// A ProtoDecoder knows how to decode various types of values from protocol +// messages. +pub struct ProtoDecoder<'a> { + inner: io::Cursor<&'a BytesMut>, +} - // Decodes a u32 value as the first step in decoding a value of the given type. - fn decode_u32_generic(&mut self, type_name: &str) -> io::Result; +/// This trait is implemented by types that can be decoded from messages with +/// a `ProtoDecoder`. +pub trait ProtoDecode: Sized { + /// Attempts to decode `self` with the given decoder. + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result; } -impl BootstrapDecode for T { +impl<'a> ProtoDecoder<'a> { + pub fn new(bytes: &'a BytesMut) -> Self { + Self{ + inner: io::Cursor::new(bytes), + } + } + + pub fn has_remaining(&self) -> bool { + self.inner.has_remaining() + } + + pub fn bytes(&self) -> &[u8] { + self.inner.bytes() + } + + // Asserts that the buffer contains at least `n` more bytes from which to + // read a value of the given type. + // Returns Ok(()) if there are that many bytes, an error otherwise. fn expect_remaining(&self, type_name: &str, n: usize) -> io::Result<()> { - if self.remaining() < n { + if self.inner.remaining() < n { Err(unexpected_eof_error(type_name)) } else { Ok(()) } } + // Decodes a u32 value as the first step in decoding a value of the given type. fn decode_u32_generic(&mut self, type_name: &str) -> io::Result { self.expect_remaining(type_name, U32_BYTE_LEN)?; - Ok(self.get_u32_le()) + Ok(self.inner.get_u32_le()) + } + + fn decode_bool(&mut self) -> io::Result { + self.expect_remaining("bool", 1)?; + match self.inner.get_u8() { + 0 => Ok(false), + 1 => Ok(true), + n => Err(invalid_data_error("bool", n)), + } + } + + fn decode_string(&mut self) -> io::Result { + let len = self.decode_u32_generic("string length")? as usize; + self.expect_remaining("string", len)?; + + let result = { + let bytes = &self.inner.bytes()[..len]; + WINDOWS_1252 + .decode(bytes, DecoderTrap::Strict) + .map_err(|err| invalid_data_error("string", (err, bytes))) + }; + + self.inner.advance(len); + result + } + + pub fn decode(&mut self) -> io::Result { + T::decode_from(self) } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - self.decode_u32_generic("u32") +impl ProtoDecode for u32 { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + decoder.decode_u32_generic("u32") } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let n = self.decode_u32_generic("u16")?; +impl ProtoDecode for u16 { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let n = decoder.decode_u32_generic("u16")?; if n > u16::MAX as u32 { return Err(invalid_data_error("u16", n)); } @@ -98,85 +146,60 @@ impl Decode for T { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - self.expect_remaining("bool", 1)?; - match self.get_u8() { - 0 => Ok(false), - 1 => Ok(true), - n => Err(invalid_data_error("bool", n)), - } +impl ProtoDecode for bool { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + decoder.decode_bool() } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let ip = self.decode_u32_generic("ipv4 address")?; +impl ProtoDecode for net::Ipv4Addr { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let ip = decoder.decode_u32_generic("ipv4 address")?; Ok(net::Ipv4Addr::from(ip)) } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let len = self.decode_u32_generic("string length")? as usize; - self.expect_remaining("string", len)?; - - let result = { - let bytes = &self.bytes()[..len]; - WINDOWS_1252 - .decode(bytes, DecoderTrap::Strict) - .map_err(|err| invalid_data_error("string", (err, bytes))) - }; - - self.advance(len); - result +impl ProtoDecode for String { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + decoder.decode_string() } } -impl Decode<(U, V)> for T -where - T: Decode + Decode, +impl ProtoDecode for (T, U) { - fn decode(&mut self) -> io::Result<(U, V)> { - let first = self.decode()?; - let second = self.decode()?; + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let first = decoder.decode()?; + let second = decoder.decode()?; Ok((first, second)) } } -impl Decode> for T -where - T: BootstrapDecode + Decode, +impl ProtoDecode for Vec { - fn decode(&mut self) -> io::Result> { - let len = self.decode_u32_generic("vector length")? as usize; + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let len = decoder.decode_u32_generic("vector length")? as usize; let mut vec = Vec::with_capacity(len); for _ in 0..len { - let val = self.decode()?; + let val = decoder.decode()?; vec.push(val); } Ok(vec) } } +// A `ProtoEncoder` knows how to encode various types of values into protocol +// messages. +pub struct ProtoEncoder<'a> { + inner: &'a mut BytesMut, +} + /// This trait is implemented by types that can be encoded into messages with /// a `ProtoEncoder`. -/// Only here to enable `ProtoEncoder::encode_vec`. -/// Attempting to implement Encode for Vec otherwise fails because none of -/// the types involved are defined in this crate. pub trait ProtoEncode { /// Attempts to encode `self` with the given encoder. fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()>; } -// A `ProtoEncoder` knows how to encode various types of values into protocol -// messages. -pub struct ProtoEncoder<'a> { - // We would like to store an &'a BufMut instead, but not only is it not - // object-safe yet, it does not grow the buffer on writes either... - inner: &'a mut BytesMut, -} - impl<'a> ProtoEncoder<'a> { pub fn new(inner: &'a mut BytesMut) -> Self { ProtoEncoder { inner: inner } @@ -188,14 +211,8 @@ impl<'a> ProtoEncoder<'a> { Ok(()) } - pub fn encode_u16(&mut self, val: u16) -> io::Result<()> { - self.encode_u32(val as u32) - } - pub fn encode_bool(&mut self, val: bool) -> io::Result<()> { - if !self.inner.has_remaining_mut() { - self.inner.reserve(1); - } + self.inner.reserve(1); self.inner.put_u8(val as u8); Ok(()) } @@ -221,21 +238,8 @@ impl<'a> ProtoEncoder<'a> { Ok(()) } - pub fn encode_pair(&mut self, pair: &(T, U)) -> io::Result<()> - where - T: ProtoEncode, - U: ProtoEncode, - { - pair.0.encode(self)?; - pair.1.encode(self) - } - - pub fn encode_vec(&mut self, vec: &[T]) -> io::Result<()> { - self.encode_u32(vec.len() as u32)?; - for ref item in vec { - item.encode(self)?; - } - Ok(()) + pub fn encode(&mut self, val: &T) -> io::Result<()> { + val.encode(self) } } @@ -253,7 +257,7 @@ impl ProtoEncode for bool { impl ProtoEncode for u16 { fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { - encoder.encode_u16(*self) + encoder.encode_u32(*self as u32) } } @@ -263,10 +267,10 @@ impl ProtoEncode for net::Ipv4Addr { } } -// It would be nice to use AsRef for the following stringy types instead -// of having to spell them out, but trying that fails because E0119: -// "upstream crates may add new impl of trait `core::convert::AsRef` for -// type `bool` in future versions". +// It would be nice to use AsRef, or Deref for the following +// stringy types instead of having to spell them out, but trying that fails +// because E0119: "upstream crates may add new impl of trait +// `core::convert::AsRef` for type `bool` in future versions". // We could probably work around this with more complex type logic (e.g. // wrapping primitive types in a newtype for which we implement // Proto{De,En}code) but it is not really worth the hassle. @@ -277,12 +281,6 @@ impl ProtoEncode for str { } } -impl<'a> ProtoEncode for &'a str { - fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { - encoder.encode_string(self) - } -} - impl ProtoEncode for String { fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { encoder.encode_string(self) @@ -297,19 +295,25 @@ impl<'a> ProtoEncode for &'a String { impl ProtoEncode for (T, U) { fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { - encoder.encode_pair(self) + self.0.encode(encoder)?; + self.1.encode(encoder) } } -impl ProtoEncode for Vec { +impl ProtoEncode for [T] { fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { - encoder.encode_vec(self) + encoder.encode_u32(self.len() as u32)?; + for ref item in self { + item.encode(encoder)?; + } + Ok(()) } } -impl<'a, T: ProtoEncode> Encode<&'a T> for BytesMut { - fn encode(&mut self, value: &'a T) -> io::Result<()> { - value.encode(&mut ProtoEncoder::new(self)) +impl ProtoEncode for Vec { + fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { + let slice: &[T] = &*self; + slice.encode(encoder) } } @@ -325,19 +329,21 @@ pub mod tests { use std::u16; use std::u32; - use bytes::{Buf, BytesMut}; + use bytes::BytesMut; - use super::{Decode, ProtoEncode, ProtoEncoder}; + use super::{ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder}; + + // Declared here because assert_eq!(bytes, &[]) fails to infer types. + const EMPTY_BYTES: &'static [u8] = &[]; pub fn roundtrip(input: T) where - T: fmt::Debug + Eq + PartialEq + ProtoEncode, - io::Cursor: Decode, + T: fmt::Debug + Eq + PartialEq + ProtoEncode + ProtoDecode, { let mut bytes = BytesMut::new(); - input.encode(&mut ProtoEncoder::new(&mut bytes)).unwrap(); - let output: T = io::Cursor::new(bytes).decode().unwrap(); + ProtoEncoder::new(&mut bytes).encode(&input).unwrap(); + let output = ProtoDecoder::new(&bytes).decode::().unwrap(); assert_eq!(output, input); } @@ -364,11 +370,6 @@ pub mod tests { } } - // Helper for succinctness in tests below. - fn new_cursor(vec: Vec) -> io::Cursor { - io::Cursor::new(BytesMut::from(vec)) - } - // A few integers and their corresponding byte encodings. const U32_ENCODINGS: [(u32, [u8; 4]); 8] = [ (0, [0, 0, 0, 0]), @@ -426,10 +427,13 @@ pub mod tests { #[test] fn decode_u32() { for &(expected_val, ref bytes) in &U32_ENCODINGS { - let mut cursor = new_cursor(bytes.to_vec()); - let val: u32 = cursor.decode().unwrap(); + let buffer = BytesMut::from(bytes.to_vec()); + let mut decoder = ProtoDecoder::new(&buffer); + + let val = decoder.decode::().unwrap(); + assert_eq!(val, expected_val); - assert_eq!(cursor.remaining(), 0); + assert_eq!(decoder.bytes(), EMPTY_BYTES); } } @@ -442,43 +446,63 @@ pub mod tests { #[test] fn decode_u32_unexpected_eof() { - let result: io::Result = new_cursor(vec![13]).decode(); + let buffer = BytesMut::from(vec![13]); + let mut decoder = ProtoDecoder::new(&buffer); + + let result = decoder.decode::(); + expect_io_error(result, io::ErrorKind::UnexpectedEof, "reading u32"); + assert_eq!(decoder.bytes(), &[13]); } #[test] fn encode_bool() { let mut bytes = BytesMut::from(vec![13]); ProtoEncoder::new(&mut bytes).encode_bool(false).unwrap(); - assert_eq!(*bytes, [13, 0]); + assert_eq!(bytes, vec![13, 0]); bytes.truncate(1); ProtoEncoder::new(&mut bytes).encode_bool(true).unwrap(); - assert_eq!(*bytes, [13, 1]); + assert_eq!(bytes, vec![13, 1]); } #[test] - fn decode_bool() { - let mut cursor = new_cursor(vec![0]); - let val: bool = cursor.decode().unwrap(); + fn decode_bool_false() { + let buffer = BytesMut::from(vec![0]); + let mut decoder = ProtoDecoder::new(&buffer); + + let val = decoder.decode::().unwrap(); + assert!(!val); - assert_eq!(cursor.remaining(), 0); + assert_eq!(decoder.bytes(), EMPTY_BYTES); + } + + #[test] + fn decode_bool_true() { + let buffer = BytesMut::from(vec![1]); + let mut decoder = ProtoDecoder::new(&buffer); + + let val = decoder.decode::().unwrap(); - cursor = new_cursor(vec![1]); - let val: bool = cursor.decode().unwrap(); assert!(val); - assert_eq!(cursor.remaining(), 0); + assert_eq!(decoder.bytes(), EMPTY_BYTES); } #[test] fn decode_bool_invalid() { - let result: io::Result = new_cursor(vec![42]).decode(); + let buffer = BytesMut::from(vec![42]); + + let result = ProtoDecoder::new(&buffer).decode::(); + expect_io_error(result, io::ErrorKind::InvalidData, "invalid bool: 42"); } #[test] fn decode_bool_unexpected_eof() { - let result: io::Result = new_cursor(vec![]).decode(); + let buffer = BytesMut::new(); + + let result = ProtoDecoder::new(&buffer).decode::(); + expect_io_error(result, io::ErrorKind::UnexpectedEof, "reading bool"); } @@ -500,7 +524,7 @@ pub mod tests { expected_bytes.extend(encoded_bytes); ProtoEncoder::new(&mut bytes) - .encode_u16(val as u16) + .encode(&(val as u16)) .unwrap(); assert_eq!(bytes, expected_bytes); } @@ -509,15 +533,16 @@ pub mod tests { #[test] fn decode_u16() { for &(expected_val, ref bytes) in &U32_ENCODINGS { - let mut cursor = new_cursor(bytes.to_vec()); + let buffer = BytesMut::from(bytes.to_vec()); + let mut decoder = ProtoDecoder::new(&buffer); + if expected_val <= u16::MAX as u32 { - let val: u16 = cursor.decode().unwrap(); + let val = decoder.decode::().unwrap(); assert_eq!(val, expected_val as u16); - assert_eq!(cursor.remaining(), 0); + assert_eq!(decoder.bytes(), EMPTY_BYTES); } else { - let result: io::Result = cursor.decode(); expect_io_error( - result, + decoder.decode::(), io::ErrorKind::InvalidData, &format!("invalid u16: {}", expected_val), ); @@ -527,7 +552,11 @@ pub mod tests { #[test] fn decode_u16_unexpected_eof() { - let result: io::Result = new_cursor(vec![]).decode(); + let buffer = BytesMut::new(); + let mut decoder = ProtoDecoder::new(&buffer); + + let result = decoder.decode::(); + expect_io_error(result, io::ErrorKind::UnexpectedEof, "reading u16"); } @@ -558,10 +587,13 @@ pub mod tests { #[test] fn decode_ipv4() { for &(expected_val, ref bytes) in &U32_ENCODINGS { - let mut cursor = new_cursor(bytes.to_vec()); - let val: net::Ipv4Addr = cursor.decode().unwrap(); + let buffer = BytesMut::from(bytes.to_vec()); + let mut decoder = ProtoDecoder::new(&buffer); + + let val = decoder.decode::().unwrap(); + assert_eq!(val, net::Ipv4Addr::from(expected_val)); - assert_eq!(cursor.remaining(), 0); + assert_eq!(decoder.bytes(), EMPTY_BYTES); } } @@ -604,10 +636,13 @@ pub mod tests { #[test] fn decode_string() { for &(expected_string, bytes) in &STRING_ENCODINGS { - let mut cursor = new_cursor(bytes.to_vec()); - let string: String = cursor.decode().unwrap(); + let buffer = BytesMut::from(bytes); + let mut decoder = ProtoDecoder::new(&buffer); + + let string = decoder.decode::().unwrap(); + assert_eq!(string, expected_string); - assert_eq!(cursor.remaining(), 0); + assert_eq!(decoder.bytes(), EMPTY_BYTES); } } @@ -630,7 +665,7 @@ pub mod tests { expected_bytes.extend(expected_string_bytes); ProtoEncoder::new(&mut bytes) - .encode_pair(&(integer, string)) + .encode(&(integer, string.to_string())) .unwrap(); assert_eq!(bytes, expected_bytes); @@ -646,12 +681,13 @@ pub mod tests { bytes.extend(integer_bytes); bytes.extend(string_bytes); - let mut cursor = new_cursor(bytes); + let buffer = BytesMut::from(bytes); + let mut decoder = ProtoDecoder::new(&buffer); - let pair: (u32, String) = cursor.decode().unwrap(); + let pair = decoder.decode::<(u32, String)>().unwrap(); assert_eq!(pair, (expected_integer, expected_string.to_string())); - assert_eq!(cursor.remaining(), 0); + assert_eq!(decoder.bytes(), EMPTY_BYTES); } #[test] @@ -669,7 +705,7 @@ pub mod tests { } let mut bytes = BytesMut::from(vec![13]); - ProtoEncoder::new(&mut bytes).encode_vec(&vec).unwrap(); + ProtoEncoder::new(&mut bytes).encode(&vec).unwrap(); assert_eq!(bytes, expected_bytes); } @@ -683,11 +719,13 @@ pub mod tests { bytes.extend(encoded_bytes); } - let mut cursor = new_cursor(bytes); - let vec: Vec = cursor.decode().unwrap(); + let buffer = BytesMut::from(bytes); + let mut decoder = ProtoDecoder::new(&buffer); + + let vec = decoder.decode::>().unwrap(); assert_eq!(vec, expected_vec); - assert_eq!(cursor.remaining(), 0); + assert_eq!(decoder.bytes(), EMPTY_BYTES); } #[test] diff --git a/src/proto/handler.rs b/src/proto/handler.rs index ad55564..315c5d5 100644 --- a/src/proto/handler.rs +++ b/src/proto/handler.rs @@ -197,8 +197,7 @@ impl Handler { mio::Token(peer_id), mio::Ready::all(), mio::PollOpt::edge() | mio::PollOpt::oneshot(), - ) - .unwrap(); + ).unwrap(); vacant_entry.insert(peer_stream); @@ -222,8 +221,7 @@ impl Handler { mio::Token(SERVER_TOKEN), event_set, mio::PollOpt::edge() | mio::PollOpt::oneshot(), - ) - .unwrap(); + ).unwrap(); } } } @@ -250,8 +248,7 @@ impl Handler { token, event_set, mio::PollOpt::edge() | mio::PollOpt::oneshot(), - ) - .unwrap(); + ).unwrap(); } } } @@ -289,8 +286,7 @@ impl mio::deprecated::Handler for Handler { token, mio::Ready::all(), mio::PollOpt::edge() | mio::PollOpt::oneshot(), - ) - .unwrap(); + ).unwrap(); } mio::Token(SERVER_TOKEN) => { diff --git a/src/proto/mod.rs b/src/proto/mod.rs index 73c4b74..f93fb13 100644 --- a/src/proto/mod.rs +++ b/src/proto/mod.rs @@ -9,7 +9,7 @@ mod stream; mod transport; mod user; -pub use self::base_codec::{Decode, ProtoEncode, ProtoEncoder}; +pub use self::base_codec::{Decode, ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder}; pub use self::codec::*; pub use self::handler::*; pub use self::packet::*; diff --git a/src/proto/peer/message.rs b/src/proto/peer/message.rs index be31f0a..83197e8 100644 --- a/src/proto/peer/message.rs +++ b/src/proto/peer/message.rs @@ -1,10 +1,8 @@ use std::io; -use bytes; - use proto::peer::constants::*; use proto::{ - Decode, MutPacket, Packet, PacketReadError, ProtoEncode, ProtoEncoder, ReadFromPacket, + MutPacket, Packet, PacketReadError, ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder, ReadFromPacket, WriteToPacket, }; @@ -43,16 +41,16 @@ impl ReadFromPacket for Message { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let code: u32 = self.decode()?; +impl ProtoDecode for Message { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let code: u32 = decoder.decode()?; let message = match code { CODE_PIERCE_FIREWALL => { - let val = self.decode()?; + let val = decoder.decode()?; Message::PierceFirewall(val) } CODE_PEER_INIT => { - let peer_init = self.decode()?; + let peer_init = decoder.decode()?; Message::PeerInit(peer_init) } _ => { @@ -140,11 +138,11 @@ impl ProtoEncode for PeerInit { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let user_name = self.decode()?; - let connection_type = self.decode()?; - let token = self.decode()?; +impl ProtoDecode for PeerInit { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let user_name = decoder.decode()?; + let connection_type = decoder.decode()?; + let token = decoder.decode()?; Ok(PeerInit { user_name, connection_type, @@ -160,16 +158,15 @@ mod tests { use bytes::BytesMut; use proto::base_codec::tests::{expect_io_error, roundtrip}; - use proto::{Decode, ProtoEncoder}; + use proto::ProtoDecoder; use super::*; #[test] fn invalid_code() { - let mut bytes = BytesMut::new(); - ProtoEncoder::new(&mut bytes).encode_u32(1337).unwrap(); + let bytes = BytesMut::from(vec![57, 5, 0, 0]); - let result: io::Result = io::Cursor::new(bytes).decode(); + let result = ProtoDecoder::new(&bytes).decode::(); expect_io_error( result, diff --git a/src/proto/server/request.rs b/src/proto/server/request.rs index b50cc22..656ef3a 100644 --- a/src/proto/server/request.rs +++ b/src/proto/server/request.rs @@ -1,12 +1,11 @@ use std::io; -use bytes; use crypto::digest::Digest; use crypto::md5::Md5; use proto::packet::{MutPacket, WriteToPacket}; use proto::server::constants::*; -use proto::{Decode, ProtoEncode, ProtoEncoder}; +use proto::{ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder}; /* ------- * * Helpers * @@ -149,49 +148,49 @@ impl ProtoEncode for ServerRequest { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let code: u32 = self.decode()?; +impl ProtoDecode for ServerRequest { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let code: u32 = decoder.decode()?; let request = match code { CODE_CANNOT_CONNECT => { - let request = self.decode()?; + let request = decoder.decode()?; ServerRequest::CannotConnectRequest(request) } CODE_CONNECT_TO_PEER => { - let request = self.decode()?; + let request = decoder.decode()?; ServerRequest::ConnectToPeerRequest(request) } CODE_FILE_SEARCH => { - let request = self.decode()?; + let request = decoder.decode()?; ServerRequest::FileSearchRequest(request) } CODE_LOGIN => { - let request = self.decode()?; + let request = decoder.decode()?; ServerRequest::LoginRequest(request) } CODE_PEER_ADDRESS => { - let request = self.decode()?; + let request = decoder.decode()?; ServerRequest::PeerAddressRequest(request) } CODE_ROOM_JOIN => { - let request = self.decode()?; + let request = decoder.decode()?; ServerRequest::RoomJoinRequest(request) } CODE_ROOM_LEAVE => { - let request = self.decode()?; + let request = decoder.decode()?; ServerRequest::RoomLeaveRequest(request) } CODE_ROOM_LIST => ServerRequest::RoomListRequest, CODE_ROOM_MESSAGE => { - let request = self.decode()?; + let request = decoder.decode()?; ServerRequest::RoomMessageRequest(request) } CODE_SET_LISTEN_PORT => { - let request = self.decode()?; + let request = decoder.decode()?; ServerRequest::SetListenPortRequest(request) } CODE_USER_STATUS => { - let request = self.decode()?; + let request = decoder.decode()?; ServerRequest::UserStatusRequest(request) } _ => { @@ -230,10 +229,10 @@ impl ProtoEncode for CannotConnectRequest { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let token = self.decode()?; - let user_name = self.decode()?; +impl ProtoDecode for CannotConnectRequest { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let token = decoder.decode()?; + let user_name = decoder.decode()?; Ok(CannotConnectRequest { token, user_name }) } } @@ -266,11 +265,11 @@ impl ProtoEncode for ConnectToPeerRequest { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let token = self.decode()?; - let user_name = self.decode()?; - let connection_type = self.decode()?; +impl ProtoDecode for ConnectToPeerRequest { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let token = decoder.decode()?; + let user_name = decoder.decode()?; + let connection_type = decoder.decode()?; Ok(ConnectToPeerRequest { token, user_name, @@ -304,10 +303,10 @@ impl ProtoEncode for FileSearchRequest { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let ticket = self.decode()?; - let query = self.decode()?; +impl ProtoDecode for FileSearchRequest { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let ticket = decoder.decode()?; + let query = decoder.decode()?; Ok(FileSearchRequest { ticket, query }) } } @@ -376,13 +375,13 @@ impl ProtoEncode for LoginRequest { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let username = self.decode()?; - let password = self.decode()?; - let major = self.decode()?; - let digest = self.decode()?; - let minor = self.decode()?; +impl ProtoDecode for LoginRequest { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let username = decoder.decode()?; + let password = decoder.decode()?; + let major = decoder.decode()?; + let digest = decoder.decode()?; + let minor = decoder.decode()?; Ok(LoginRequest { username, password, @@ -415,9 +414,9 @@ impl ProtoEncode for PeerAddressRequest { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let username = self.decode()?; +impl ProtoDecode for PeerAddressRequest { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let username = decoder.decode()?; Ok(PeerAddressRequest { username: username }) } } @@ -444,9 +443,9 @@ impl ProtoEncode for RoomJoinRequest { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let room_name = self.decode()?; +impl ProtoDecode for RoomJoinRequest { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let room_name = decoder.decode()?; Ok(RoomJoinRequest { room_name: room_name, }) @@ -475,9 +474,9 @@ impl ProtoEncode for RoomLeaveRequest { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let room_name = self.decode()?; +impl ProtoDecode for RoomLeaveRequest { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let room_name = decoder.decode()?; Ok(RoomLeaveRequest { room_name: room_name, }) @@ -509,10 +508,10 @@ impl ProtoEncode for RoomMessageRequest { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let room_name = self.decode()?; - let message = self.decode()?; +impl ProtoDecode for RoomMessageRequest { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let room_name = decoder.decode()?; + let message = decoder.decode()?; Ok(RoomMessageRequest { room_name, message }) } } @@ -535,13 +534,13 @@ impl WriteToPacket for SetListenPortRequest { impl ProtoEncode for SetListenPortRequest { fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> { - encoder.encode_u16(self.port) + encoder.encode(&self.port) } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let port = self.decode()?; +impl ProtoDecode for SetListenPortRequest { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let port = decoder.decode()?; Ok(SetListenPortRequest { port: port }) } } @@ -568,9 +567,9 @@ impl ProtoEncode for UserStatusRequest { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let user_name = self.decode()?; +impl ProtoDecode for UserStatusRequest { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let user_name = decoder.decode()?; Ok(UserStatusRequest { user_name: user_name, }) @@ -588,16 +587,16 @@ mod tests { use bytes::BytesMut; use proto::base_codec::tests::{expect_io_error, roundtrip}; - use proto::{Decode, ProtoEncoder}; + use proto::ProtoDecoder; use super::*; #[test] fn invalid_code() { - let mut bytes = BytesMut::new(); - ProtoEncoder::new(&mut bytes).encode_u32(1337).unwrap(); + let bytes = BytesMut::from(vec![57, 5, 0, 0]); + + let result = ProtoDecoder::new(&bytes).decode::(); - let result: io::Result = io::Cursor::new(bytes).decode(); expect_io_error( result, io::ErrorKind::InvalidData, diff --git a/src/proto/server/response.rs b/src/proto/server/response.rs index db891b2..6065498 100644 --- a/src/proto/server/response.rs +++ b/src/proto/server/response.rs @@ -1,11 +1,9 @@ use std::io; use std::net; -use bytes; - use proto::packet::{Packet, PacketReadError, ReadFromPacket}; use proto::server::constants::*; -use proto::{Decode, ProtoEncode, ProtoEncoder, User, UserStatus}; +use proto::{ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder, User, UserStatus}; /*=================* * SERVER RESPONSE * @@ -178,76 +176,76 @@ impl ProtoEncode for ServerResponse { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let code: u32 = self.decode()?; +impl ProtoDecode for ServerResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let code: u32 = decoder.decode()?; let response = match code { CODE_CONNECT_TO_PEER => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::ConnectToPeerResponse(response) } CODE_FILE_SEARCH => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::FileSearchResponse(response) } CODE_LOGIN => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::LoginResponse(response) } CODE_PARENT_MIN_SPEED => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::ParentMinSpeedResponse(response) } CODE_PARENT_SPEED_RATIO => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::ParentSpeedRatioResponse(response) } CODE_PEER_ADDRESS => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::PeerAddressResponse(response) } CODE_PRIVILEGED_USERS => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::PrivilegedUsersResponse(response) } CODE_ROOM_JOIN => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::RoomJoinResponse(response) } CODE_ROOM_LEAVE => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::RoomLeaveResponse(response) } CODE_ROOM_LIST => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::RoomListResponse(response) } CODE_ROOM_MESSAGE => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::RoomMessageResponse(response) } CODE_ROOM_TICKERS => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::RoomTickersResponse(response) } CODE_ROOM_USER_JOINED => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::RoomUserJoinedResponse(response) } CODE_ROOM_USER_LEFT => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::RoomUserLeftResponse(response) } CODE_USER_INFO => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::UserInfoResponse(response) } CODE_USER_STATUS => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::UserStatusResponse(response) } CODE_WISHLIST_INTERVAL => { - let response = self.decode()?; + let response = decoder.decode()?; ServerResponse::WishlistIntervalResponse(response) } _ => { @@ -300,20 +298,20 @@ impl ProtoEncode for ConnectToPeerResponse { encoder.encode_string(&self.user_name)?; encoder.encode_string(&self.connection_type)?; encoder.encode_ipv4_addr(self.ip)?; - encoder.encode_u16(self.port)?; + encoder.encode(&self.port)?; encoder.encode_u32(self.token)?; encoder.encode_bool(self.is_privileged) } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let user_name = self.decode()?; - let connection_type = self.decode()?; - let ip = self.decode()?; - let port = self.decode()?; - let token = self.decode()?; - let is_privileged = self.decode()?; +impl ProtoDecode for ConnectToPeerResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let user_name = decoder.decode()?; + let connection_type = decoder.decode()?; + let ip = decoder.decode()?; + let port = decoder.decode()?; + let token = decoder.decode()?; + let is_privileged = decoder.decode()?; Ok(ConnectToPeerResponse { user_name, @@ -359,11 +357,11 @@ impl ProtoEncode for FileSearchResponse { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let user_name = self.decode()?; - let ticket = self.decode()?; - let query = self.decode()?; +impl ProtoDecode for FileSearchResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let user_name = decoder.decode()?; + let ticket = decoder.decode()?; + let query = decoder.decode()?; Ok(FileSearchResponse { user_name, @@ -435,18 +433,18 @@ impl ProtoEncode for LoginResponse { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let ok: bool = self.decode()?; +impl ProtoDecode for LoginResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let ok: bool = decoder.decode()?; if !ok { - let reason = self.decode()?; + let reason = decoder.decode()?; return Ok(LoginResponse::LoginFail { reason }); } - let motd = self.decode()?; - let ip = self.decode()?; + let motd = decoder.decode()?; + let ip = decoder.decode()?; - let result: io::Result = self.decode(); + let result: io::Result = decoder.decode(); match result { Ok(value) => debug!("LoginResponse last field: {}", value), Err(e) => debug!("Error reading LoginResponse field: {:?}", e), @@ -482,9 +480,9 @@ impl ProtoEncode for ParentMinSpeedResponse { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let value = self.decode()?; +impl ProtoDecode for ParentMinSpeedResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let value = decoder.decode()?; Ok(ParentMinSpeedResponse { value }) } } @@ -511,9 +509,9 @@ impl ProtoEncode for ParentSpeedRatioResponse { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let value = self.decode()?; +impl ProtoDecode for ParentSpeedRatioResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let value = decoder.decode()?; Ok(ParentSpeedRatioResponse { value }) } } @@ -543,15 +541,15 @@ impl ProtoEncode for PeerAddressResponse { fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> { encoder.encode_string(&self.username)?; encoder.encode_ipv4_addr(self.ip)?; - encoder.encode_u16(self.port) + encoder.encode(&self.port) } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let username = self.decode()?; - let ip = self.decode()?; - let port = self.decode()?; +impl ProtoDecode for PeerAddressResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let username = decoder.decode()?; + let ip = decoder.decode()?; + let port = decoder.decode()?; Ok(PeerAddressResponse { username, ip, port }) } } @@ -574,13 +572,13 @@ impl ReadFromPacket for PrivilegedUsersResponse { impl ProtoEncode for PrivilegedUsersResponse { fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> { - encoder.encode_vec(&self.users) + encoder.encode(&self.users) } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let users = self.decode()?; +impl ProtoDecode for PrivilegedUsersResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let users = decoder.decode()?; Ok(PrivilegedUsersResponse { users }) } } @@ -742,13 +740,13 @@ impl ProtoEncode for UserInfo { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let average_speed = self.decode()?; - let num_downloads = self.decode()?; - let unknown = self.decode()?; - let num_files = self.decode()?; - let num_folders = self.decode()?; +impl ProtoDecode for UserInfo { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let average_speed = decoder.decode()?; + let num_downloads = decoder.decode()?; + let unknown = decoder.decode()?; + let num_files = decoder.decode()?; + let num_folders = decoder.decode()?; Ok(UserInfo { average_speed, num_downloads, @@ -775,15 +773,15 @@ impl ProtoEncode for RoomJoinResponse { } encoder.encode_string(&self.room_name)?; - encoder.encode_vec(&user_names)?; - encoder.encode_vec(&user_statuses)?; - encoder.encode_vec(&user_infos)?; - encoder.encode_vec(&user_free_slots)?; - encoder.encode_vec(&user_countries)?; + encoder.encode(&user_names)?; + encoder.encode(&user_statuses)?; + encoder.encode(&user_infos)?; + encoder.encode(&user_free_slots)?; + encoder.encode(&user_countries)?; if let Some(ref owner) = self.owner { encoder.encode_string(owner)?; - encoder.encode_vec(&self.operators)?; + encoder.encode(&self.operators)?; } Ok(()) @@ -818,20 +816,20 @@ fn build_users( users } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let room_name = self.decode()?; - let user_names = self.decode()?; - let user_statuses = self.decode()?; - let user_infos = self.decode()?; - let user_free_slots = self.decode()?; - let user_countries = self.decode()?; +impl ProtoDecode for RoomJoinResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let room_name = decoder.decode()?; + let user_names = decoder.decode()?; + let user_statuses = decoder.decode()?; + let user_infos = decoder.decode()?; + let user_free_slots = decoder.decode()?; + let user_countries = decoder.decode()?; let mut owner = None; let mut operators = vec![]; - if self.has_remaining() { - owner = Some(self.decode()?); - operators = self.decode()?; + if decoder.has_remaining() { + owner = Some(decoder.decode()?); + operators = decoder.decode()?; } let users = build_users( @@ -874,9 +872,9 @@ impl ProtoEncode for RoomLeaveResponse { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let room_name = self.decode()?; +impl ProtoDecode for RoomLeaveResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let room_name = decoder.decode()?; Ok(RoomLeaveResponse { room_name }) } } @@ -964,9 +962,9 @@ impl RoomListResponse { rooms } - fn decode_rooms(buf: &mut T) -> io::Result> { - let room_names = buf.decode()?; - let user_counts = buf.decode()?; + fn decode_rooms(decoder: &mut ProtoDecoder) -> io::Result> { + let room_names = decoder.decode()?; + let user_counts = decoder.decode()?; Ok(Self::build_rooms(room_names, user_counts)) } @@ -979,8 +977,8 @@ impl RoomListResponse { user_counts.push(user_count); } - encoder.encode_vec(&room_names)?; - encoder.encode_vec(&user_counts) + encoder.encode(&room_names)?; + encoder.encode(&user_counts) } } @@ -989,16 +987,16 @@ impl ProtoEncode for RoomListResponse { Self::encode_rooms(&self.rooms, encoder)?; Self::encode_rooms(&self.owned_private_rooms, encoder)?; Self::encode_rooms(&self.other_private_rooms, encoder)?; - encoder.encode_vec(&self.operated_private_room_names) + encoder.encode(&self.operated_private_room_names) } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let rooms = RoomListResponse::decode_rooms(self)?; - let owned_private_rooms = RoomListResponse::decode_rooms(self)?; - let other_private_rooms = RoomListResponse::decode_rooms(self)?; - let operated_private_room_names = self.decode()?; +impl ProtoDecode for RoomListResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let rooms = RoomListResponse::decode_rooms(decoder)?; + let owned_private_rooms = RoomListResponse::decode_rooms(decoder)?; + let other_private_rooms = RoomListResponse::decode_rooms(decoder)?; + let operated_private_room_names = decoder.decode()?; Ok(RoomListResponse { rooms, owned_private_rooms, @@ -1040,11 +1038,11 @@ impl ProtoEncode for RoomMessageResponse { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let room_name = self.decode()?; - let user_name = self.decode()?; - let message = self.decode()?; +impl ProtoDecode for RoomMessageResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let room_name = decoder.decode()?; + let user_name = decoder.decode()?; + let message = decoder.decode()?; Ok(RoomMessageResponse { room_name, user_name, @@ -1082,14 +1080,14 @@ impl ReadFromPacket for RoomTickersResponse { impl ProtoEncode for RoomTickersResponse { fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { encoder.encode_string(&self.room_name)?; - encoder.encode_vec(&self.tickers) + encoder.encode(&self.tickers) } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let room_name = self.decode()?; - let tickers = self.decode()?; +impl ProtoDecode for RoomTickersResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let room_name = decoder.decode()?; + let tickers = decoder.decode()?; Ok(RoomTickersResponse { room_name, tickers }) } } @@ -1148,14 +1146,14 @@ impl ProtoEncode for RoomUserJoinedResponse { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let room_name = self.decode()?; - let user_name = self.decode()?; - let status = self.decode()?; - let info = self.decode()?; - let num_free_slots = self.decode()?; - let country = self.decode()?; +impl ProtoDecode for RoomUserJoinedResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let room_name = decoder.decode()?; + let user_name = decoder.decode()?; + let status = decoder.decode()?; + let info = decoder.decode()?; + let num_free_slots = decoder.decode()?; + let country = decoder.decode()?; Ok(RoomUserJoinedResponse { room_name, user: build_user(user_name, status, info, num_free_slots, country), @@ -1191,10 +1189,10 @@ impl ProtoEncode for RoomUserLeftResponse { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let room_name = self.decode()?; - let user_name = self.decode()?; +impl ProtoDecode for RoomUserLeftResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let room_name = decoder.decode()?; + let user_name = decoder.decode()?; Ok(RoomUserLeftResponse { room_name, user_name, @@ -1242,13 +1240,13 @@ impl ProtoEncode for UserInfoResponse { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let user_name = self.decode()?; - let average_speed: u32 = self.decode()?; - let num_downloads: u32 = self.decode()?; - let num_files: u32 = self.decode()?; - let num_folders: u32 = self.decode()?; +impl ProtoDecode for UserInfoResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let user_name = decoder.decode()?; + let average_speed: u32 = decoder.decode()?; + let num_downloads: u32 = decoder.decode()?; + let num_files: u32 = decoder.decode()?; + let num_folders: u32 = decoder.decode()?; Ok(UserInfoResponse { user_name, average_speed: average_speed as usize, @@ -1291,11 +1289,11 @@ impl ProtoEncode for UserStatusResponse { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let user_name = self.decode()?; - let status = self.decode()?; - let is_privileged = self.decode()?; +impl ProtoDecode for UserStatusResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let user_name = decoder.decode()?; + let status = decoder.decode()?; + let is_privileged = decoder.decode()?; Ok(UserStatusResponse { user_name, status, @@ -1326,9 +1324,9 @@ impl ProtoEncode for WishlistIntervalResponse { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let seconds = self.decode()?; +impl ProtoDecode for WishlistIntervalResponse { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let seconds = decoder.decode()?; Ok(WishlistIntervalResponse { seconds }) } } @@ -1345,16 +1343,15 @@ mod tests { use bytes::BytesMut; use proto::base_codec::tests::{expect_io_error, roundtrip}; - use proto::{Decode, ProtoEncoder}; + use proto::ProtoDecoder; use super::*; #[test] fn invalid_code() { - let mut bytes = BytesMut::new(); - ProtoEncoder::new(&mut bytes).encode_u32(1337).unwrap(); + let bytes = BytesMut::from(vec![57, 5, 0, 0]); - let result: io::Result = io::Cursor::new(bytes).decode(); + let result = ProtoDecoder::new(&bytes).decode::(); expect_io_error( result, diff --git a/src/proto/transport.rs b/src/proto/transport.rs index dcd73c1..31f0515 100644 --- a/src/proto/transport.rs +++ b/src/proto/transport.rs @@ -1,26 +1,25 @@ use std::fmt; use std::io; -use bytes::{Buf, BytesMut}; +use bytes::BytesMut; use tokio_io::codec::length_delimited::{Builder, Framed}; use tokio_io::{AsyncRead, AsyncWrite}; use proto::peer; -use proto::{Decode, ProtoEncode, ProtoEncoder, ServerRequest, ServerResponse}; +use proto::{ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder, ServerRequest, ServerResponse}; fn decode_frame<'a, T>(frame_type: &str, bytes: &'a mut BytesMut) -> io::Result where - T: fmt::Debug, - io::Cursor<&'a mut BytesMut>: Decode, + T: ProtoDecode + fmt::Debug, { - let mut cursor = io::Cursor::new(bytes); - let frame = cursor.decode()?; - if cursor.has_remaining() { + let mut decoder = ProtoDecoder::new(&*bytes); + let frame = decoder.decode()?; + if decoder.has_remaining() { warn!( "Received {} with trailing bytes. Frame:\n{:?}Bytes:{:?}", frame_type, frame, - cursor.bytes() + decoder.bytes() ); } Ok(frame) diff --git a/src/proto/user.rs b/src/proto/user.rs index d54ce35..ab7759e 100644 --- a/src/proto/user.rs +++ b/src/proto/user.rs @@ -1,9 +1,7 @@ use std::io; -use bytes; - use proto::{ - Decode, MutPacket, Packet, PacketReadError, ProtoEncode, ProtoEncoder, ReadFromPacket, + MutPacket, Packet, PacketReadError, ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder, ReadFromPacket, WriteToPacket, }; @@ -57,9 +55,9 @@ impl ProtoEncode for UserStatus { } } -impl Decode for T { - fn decode(&mut self) -> io::Result { - let value: u32 = self.decode()?; +impl ProtoDecode for UserStatus { + fn decode_from(decoder: &mut ProtoDecoder) -> io::Result { + let value: u32 = decoder.decode()?; match value { STATUS_OFFLINE => Ok(UserStatus::Offline), STATUS_AWAY => Ok(UserStatus::Away),