From 5a980dbba166dff4eaa69cc0685c850d4d633646 Mon Sep 17 00:00:00 2001 From: Titouan Rigoudy Date: Sat, 13 Jan 2018 19:26:56 -0500 Subject: [PATCH] Replace ProtoDecode with Decode, remove ProtoDecoder. --- src/proto/codec.rs | 250 +++++++++++++------------------ src/proto/mod.rs | 2 +- src/proto/peer/message.rs | 32 ++-- src/proto/server/request.rs | 133 +++++++++-------- src/proto/server/response.rs | 281 ++++++++++++++++++----------------- src/proto/transport.rs | 4 +- src/proto/user.rs | 12 +- 7 files changed, 339 insertions(+), 375 deletions(-) diff --git a/src/proto/codec.rs b/src/proto/codec.rs index 8bf746c..7b98839 100644 --- a/src/proto/codec.rs +++ b/src/proto/codec.rs @@ -31,142 +31,145 @@ const U32_BYTE_LEN: usize = 4; // * Pairs are serialized as two consecutive values. // * Vectors are serialized as length-prefixed arrays of serialized values. -/// This trait is implemented by types that can be decoded from messages with -/// a `ProtoDecoder`. -/// Only here to enable `ProtoDecoder::decode_vec`. -pub trait ProtoDecode: Sized { - /// Attempts to decode an instance of `Self` using the given decoder. - fn decode(decoder: &mut ProtoDecoder) -> io::Result; +pub trait Decode { + /// Attempts to decode an istance of `T` from `self`. + fn decode(&mut self) -> io::Result; } -/// This trait is implemented by types that can be encoded into messages with -/// a `ProtoEncoder`. -/// Only here to enable `ProtoEncoder::encode_vec`. -pub trait ProtoEncode { - /// Attempts to encode `self` with the given encoder. - fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()>; +pub trait Encode { + /// Attempts to encode `value` into `self`. + fn encode(&mut self, value: T) -> io::Result<()>; } -// A `ProtoDecoder` knows how to decode various types of values from protocol -// messages. -pub struct ProtoDecoder<'a> { - // If bytes::Buf was object-safe we would just store &'a Buf. We work - // around this limitation by explicitly naming the implementing type. - inner: &'a mut io::Cursor, +// Builds an EOF error encountered when reading a value of the given type. +fn unexpected_eof_error(type_name: &str) -> io::Error { + io::Error::new( + io::ErrorKind::UnexpectedEof, + format!("reading {}", type_name), + ) } -impl<'a> ProtoDecoder<'a> { - pub fn new(inner: &'a mut io::Cursor) -> Self { - ProtoDecoder { inner: inner } - } - - // Private helper methods - // ---------------------- +// Builds an InvalidData error for the given value of the given type. +fn invalid_data_error(type_name: &str, value: T) -> io::Error { + io::Error::new( + io::ErrorKind::InvalidData, + format!("invalid {}: {:?}", type_name, value), + ) +} - // Builds an EOF error encountered when reading a value of the given type. - fn unexpected_eof_error(type_name: &str) -> io::Error { - io::Error::new( - io::ErrorKind::UnexpectedEof, - format!("reading {}", type_name), - ) - } +// 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<()>; - // Builds an InvalidData error for the given value of the given type. - fn invalid_data_error(type_name: &str, value: T) -> io::Error { - io::Error::new( - io::ErrorKind::InvalidData, - format!("invalid {}: {:?}", type_name, value), - ) - } + // 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; +} - // Asserts that the underlying 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(&mut self, type_name: &str, n: usize) -> io::Result<()> { - if self.inner.remaining() < n { - Err(Self::unexpected_eof_error(type_name)) +impl BootstrapDecode for T { + fn expect_remaining(&self, type_name: &str, n: usize) -> io::Result<()> { + if self.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.inner.get_u32::()) - } - - // Public methods - // -------------- - - pub fn has_remaining(&self) -> bool { - self.inner.has_remaining() + Ok(self.get_u32::()) } +} - pub fn decode_u32(&mut self) -> io::Result { +impl Decode for T { + fn decode(&mut self) -> io::Result { self.decode_u32_generic("u32") } +} - pub fn decode_u16(&mut self) -> io::Result { +impl Decode for T { + fn decode(&mut self) -> io::Result { let n = self.decode_u32_generic("u16")?; if n > u16::MAX as u32 { - return Err(Self::invalid_data_error("u16", n)); + return Err(invalid_data_error("u16", n)); } Ok(n as u16) } +} - pub fn decode_bool(&mut self) -> io::Result { +impl Decode for T { + fn decode(&mut self) -> io::Result { self.expect_remaining("bool", 1)?; - match self.inner.get_u8() { + match self.get_u8() { 0 => Ok(false), 1 => Ok(true), - n => Err(Self::invalid_data_error("bool", n)), + n => Err(invalid_data_error("bool", n)), } } +} - pub fn decode_ipv4_addr(&mut self) -> io::Result { +impl Decode for T { + fn decode(&mut self) -> io::Result { let ip = self.decode_u32_generic("ipv4 address")?; Ok(net::Ipv4Addr::from(ip)) } +} - pub fn decode_string(&mut self) -> io::Result { +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.inner.bytes()[..len]; + let bytes = &self.bytes()[..len]; WINDOWS_1252.decode(bytes, DecoderTrap::Strict).map_err( |err| { - Self::invalid_data_error("string", (err, bytes)) + invalid_data_error("string", (err, bytes)) }, ) }; - self.inner.advance(len); + self.advance(len); result } +} - pub fn decode_pair(&mut self) -> io::Result<(T, U)> - where - T: ProtoDecode, - U: ProtoDecode, - { - let first = T::decode(self)?; - let second = U::decode(self)?; +impl Decode<(U, V)> for T +where + T: Decode + Decode, +{ + fn decode(&mut self) -> io::Result<(U, V)> { + let first = self.decode()?; + let second = self.decode()?; Ok((first, second)) } +} - pub fn decode_vec(&mut self) -> io::Result> { +impl Decode> for T +where + T: Buf + Decode, +{ + fn decode(&mut self) -> io::Result> { let len = self.decode_u32_generic("vector length")? as usize; let mut vec = Vec::with_capacity(len); for _ in 0..len { - let val = T::decode(self)?; + let val = self.decode()?; vec.push(val); } Ok(vec) } } +/// This trait is implemented by types that can be encoded into messages with +/// a `ProtoEncoder`. +/// Only here to enable `ProtoEncoder::encode_vec`. +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> { @@ -240,60 +243,30 @@ impl<'a> ProtoEncoder<'a> { } } -impl ProtoDecode for u32 { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - decoder.decode_u32() - } -} - impl ProtoEncode for u32 { fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { encoder.encode_u32(*self) } } -impl ProtoDecode for bool { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - decoder.decode_bool() - } -} - impl ProtoEncode for bool { fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { encoder.encode_bool(*self) } } -impl ProtoDecode for u16 { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - decoder.decode_u16() - } -} - impl ProtoEncode for u16 { fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { encoder.encode_u16(*self) } } -impl ProtoDecode for net::Ipv4Addr { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - decoder.decode_ipv4_addr() - } -} - impl ProtoEncode for net::Ipv4Addr { fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { encoder.encode_ipv4_addr(*self) } } -impl ProtoDecode for String { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - decoder.decode_string() - } -} - // 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 @@ -326,24 +299,12 @@ impl<'a> ProtoEncode for &'a String { } } -impl ProtoDecode for (T, U) { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - decoder.decode_pair::() - } -} - impl ProtoEncode for (T, U) { fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { encoder.encode_pair(self) } } -impl ProtoDecode for Vec { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - decoder.decode_vec::() - } -} - impl ProtoEncode for Vec { fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { encoder.encode_vec(self) @@ -356,8 +317,6 @@ impl ProtoEncode for Vec { #[cfg(test)] pub mod tests { - use super::{ProtoDecoder, ProtoEncoder, ProtoDecode, ProtoEncode}; - use std::fmt; use std::io; use std::net; @@ -366,12 +325,17 @@ pub mod tests { use bytes::{Buf, BytesMut}; - pub fn roundtrip(input: T) { + use super::{Decode, ProtoEncoder, ProtoEncode}; + + pub fn roundtrip(input: T) + where + T: fmt::Debug + Eq + PartialEq + ProtoEncode, + io::Cursor: Decode, + { let mut bytes = BytesMut::new(); input.encode(&mut ProtoEncoder::new(&mut bytes)).unwrap(); - let mut cursor = io::Cursor::new(bytes); - let output = T::decode(&mut ProtoDecoder::new(&mut cursor)).unwrap(); + let output: T = io::Cursor::new(bytes).decode().unwrap(); assert_eq!(output, input); } @@ -461,7 +425,7 @@ pub mod tests { fn decode_u32() { for &(expected_val, ref bytes) in &U32_ENCODINGS { let mut cursor = new_cursor(bytes.to_vec()); - let val = ProtoDecoder::new(&mut cursor).decode_u32().unwrap(); + let val: u32 = cursor.decode().unwrap(); assert_eq!(val, expected_val); assert_eq!(cursor.remaining(), 0); } @@ -476,8 +440,7 @@ pub mod tests { #[test] fn decode_u32_unexpected_eof() { - let mut cursor = new_cursor(vec![13]); - let result = ProtoDecoder::new(&mut cursor).decode_u32(); + let result: io::Result = new_cursor(vec![13]).decode(); expect_io_error(result, io::ErrorKind::UnexpectedEof, "reading u32"); } @@ -495,27 +458,25 @@ pub mod tests { #[test] fn decode_bool() { let mut cursor = new_cursor(vec![0]); - let mut val = ProtoDecoder::new(&mut cursor).decode_bool().unwrap(); + let val: bool = cursor.decode().unwrap(); assert!(!val); assert_eq!(cursor.remaining(), 0); cursor = new_cursor(vec![1]); - val = ProtoDecoder::new(&mut cursor).decode_bool().unwrap(); + let val: bool = cursor.decode().unwrap(); assert!(val); assert_eq!(cursor.remaining(), 0); } #[test] fn decode_bool_invalid() { - let mut cursor = new_cursor(vec![42]); - let result = ProtoDecoder::new(&mut cursor).decode_bool(); + let result: io::Result = new_cursor(vec![42]).decode(); expect_io_error(result, io::ErrorKind::InvalidData, "invalid bool: 42"); } #[test] fn decode_bool_unexpected_eof() { - let mut cursor = new_cursor(vec![]); - let result = ProtoDecoder::new(&mut cursor).decode_bool(); + let result: io::Result = new_cursor(vec![]).decode(); expect_io_error(result, io::ErrorKind::UnexpectedEof, "reading bool"); } @@ -548,26 +509,23 @@ pub mod tests { for &(expected_val, ref bytes) in &U32_ENCODINGS { let mut cursor = new_cursor(bytes.to_vec()); if expected_val <= u16::MAX as u32 { - let val = ProtoDecoder::new(&mut cursor).decode_u16().unwrap(); + let val: u16 = cursor.decode().unwrap(); assert_eq!(val, expected_val as u16); assert_eq!(cursor.remaining(), 0); } else { - assert!(ProtoDecoder::new(&mut cursor).decode_u16().is_err()); + let result: io::Result = cursor.decode(); + expect_io_error( + result, + io::ErrorKind::InvalidData, + &format!("invalid u16: {}", expected_val), + ); } } } - #[test] - fn decode_u16_invalid() { - let mut cursor = new_cursor(vec![0, 0, 1, 0]); - let result = ProtoDecoder::new(&mut cursor).decode_u16(); - expect_io_error(result, io::ErrorKind::InvalidData, "invalid u16: 65536"); - } - #[test] fn decode_u16_unexpected_eof() { - let mut cursor = new_cursor(vec![]); - let result = ProtoDecoder::new(&mut cursor).decode_u16(); + let result: io::Result = new_cursor(vec![]).decode(); expect_io_error(result, io::ErrorKind::UnexpectedEof, "reading u16"); } @@ -599,7 +557,7 @@ pub mod tests { fn decode_ipv4() { for &(expected_val, ref bytes) in &U32_ENCODINGS { let mut cursor = new_cursor(bytes.to_vec()); - let val = ProtoDecoder::new(&mut cursor).decode_ipv4_addr().unwrap(); + let val: net::Ipv4Addr = cursor.decode().unwrap(); assert_eq!(val, net::Ipv4Addr::from(expected_val)); assert_eq!(cursor.remaining(), 0); } @@ -646,7 +604,7 @@ pub mod tests { fn decode_string() { for &(expected_string, bytes) in &STRING_ENCODINGS { let mut cursor = new_cursor(bytes.to_vec()); - let string = ProtoDecoder::new(&mut cursor).decode_string().unwrap(); + let string: String = cursor.decode().unwrap(); assert_eq!(string, expected_string); assert_eq!(cursor.remaining(), 0); } @@ -689,9 +647,7 @@ pub mod tests { let mut cursor = new_cursor(bytes); - let pair = ProtoDecoder::new(&mut cursor) - .decode_pair::() - .unwrap(); + let pair: (u32, String) = cursor.decode().unwrap(); assert_eq!(pair, (expected_integer, expected_string.to_string())); assert_eq!(cursor.remaining(), 0); @@ -727,7 +683,7 @@ pub mod tests { } let mut cursor = new_cursor(bytes); - let vec = ProtoDecoder::new(&mut cursor).decode_vec::().unwrap(); + let vec: Vec = cursor.decode().unwrap(); assert_eq!(vec, expected_vec); assert_eq!(cursor.remaining(), 0); diff --git a/src/proto/mod.rs b/src/proto/mod.rs index 5061c68..6fbc99b 100644 --- a/src/proto/mod.rs +++ b/src/proto/mod.rs @@ -8,7 +8,7 @@ mod stream; mod transport; mod user; -pub use self::codec::{ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder}; +pub use self::codec::{Decode, ProtoEncode, ProtoEncoder}; pub use self::handler::*; pub use self::packet::*; pub use self::stream::*; diff --git a/src/proto/peer/message.rs b/src/proto/peer/message.rs index c7cbea1..349e197 100644 --- a/src/proto/peer/message.rs +++ b/src/proto/peer/message.rs @@ -1,7 +1,9 @@ use std::io; -use proto::{MutPacket, Packet, PacketReadError, ProtoDecode, ProtoDecoder, ProtoEncode, - ProtoEncoder, ReadFromPacket, WriteToPacket}; +use bytes; + +use proto::{Decode, MutPacket, Packet, PacketReadError, ProtoEncode, ProtoEncoder, ReadFromPacket, + WriteToPacket}; use proto::peer::constants::*; /*=========* @@ -40,16 +42,16 @@ impl ReadFromPacket for Message { } } -impl ProtoDecode for Message { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let code = decoder.decode_u32()?; +impl Decode for T { + fn decode(&mut self) -> io::Result { + let code: u32 = self.decode()?; let message = match code { CODE_PIERCE_FIREWALL => { - let val = decoder.decode_u32()?; + let val = self.decode()?; Message::PierceFirewall(val) } CODE_PEER_INIT => { - let peer_init = PeerInit::decode(decoder)?; + let peer_init = self.decode()?; Message::PeerInit(peer_init) } _ => { @@ -137,11 +139,11 @@ impl ProtoEncode for PeerInit { } } -impl ProtoDecode for PeerInit { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let user_name = decoder.decode_string()?; - let connection_type = decoder.decode_string()?; - let token = decoder.decode_u32()?; +impl Decode for T { + fn decode(&mut self) -> io::Result { + let user_name = self.decode()?; + let connection_type = self.decode()?; + let token = self.decode()?; Ok(PeerInit { user_name, connection_type, @@ -157,7 +159,7 @@ mod tests { use bytes::BytesMut; - use proto::{ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder}; + use proto::{Decode, ProtoEncode, ProtoEncoder}; use proto::codec::tests::{expect_io_error, roundtrip}; use super::*; @@ -167,8 +169,8 @@ mod tests { let mut bytes = BytesMut::new(); ProtoEncoder::new(&mut bytes).encode_u32(1337).unwrap(); - let mut cursor = io::Cursor::new(bytes); - let result = Message::decode(&mut ProtoDecoder::new(&mut cursor)); + let result: io::Result = io::Cursor::new(bytes).decode(); + expect_io_error( result, io::ErrorKind::InvalidData, diff --git a/src/proto/server/request.rs b/src/proto/server/request.rs index 6d5e249..4fd53df 100644 --- a/src/proto/server/request.rs +++ b/src/proto/server/request.rs @@ -1,9 +1,10 @@ use std::io; +use bytes; use crypto::md5::Md5; use crypto::digest::Digest; -use proto::{ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder}; +use proto::{Decode, ProtoEncode, ProtoEncoder}; use proto::packet::{MutPacket, WriteToPacket}; use proto::server::constants::*; @@ -148,49 +149,49 @@ impl ProtoEncode for ServerRequest { } } -impl ProtoDecode for ServerRequest { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let code = decoder.decode_u32()?; +impl Decode for T { + fn decode(&mut self) -> io::Result { + let code: u32 = self.decode()?; let request = match code { CODE_CANNOT_CONNECT => { - let request = CannotConnectRequest::decode(decoder)?; + let request = self.decode()?; ServerRequest::CannotConnectRequest(request) } CODE_CONNECT_TO_PEER => { - let request = ConnectToPeerRequest::decode(decoder)?; + let request = self.decode()?; ServerRequest::ConnectToPeerRequest(request) } CODE_FILE_SEARCH => { - let request = FileSearchRequest::decode(decoder)?; + let request = self.decode()?; ServerRequest::FileSearchRequest(request) } CODE_LOGIN => { - let request = LoginRequest::decode(decoder)?; + let request = self.decode()?; ServerRequest::LoginRequest(request) } CODE_PEER_ADDRESS => { - let request = PeerAddressRequest::decode(decoder)?; + let request = self.decode()?; ServerRequest::PeerAddressRequest(request) } CODE_ROOM_JOIN => { - let request = RoomJoinRequest::decode(decoder)?; + let request = self.decode()?; ServerRequest::RoomJoinRequest(request) } CODE_ROOM_LEAVE => { - let request = RoomLeaveRequest::decode(decoder)?; + let request = self.decode()?; ServerRequest::RoomLeaveRequest(request) } CODE_ROOM_LIST => ServerRequest::RoomListRequest, CODE_ROOM_MESSAGE => { - let request = RoomMessageRequest::decode(decoder)?; + let request = self.decode()?; ServerRequest::RoomMessageRequest(request) } CODE_SET_LISTEN_PORT => { - let request = SetListenPortRequest::decode(decoder)?; + let request = self.decode()?; ServerRequest::SetListenPortRequest(request) } CODE_USER_STATUS => { - let request = UserStatusRequest::decode(decoder)?; + let request = self.decode()?; ServerRequest::UserStatusRequest(request) } _ => { @@ -229,11 +230,11 @@ impl ProtoEncode for CannotConnectRequest { } } -impl ProtoDecode for CannotConnectRequest { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let token = decoder.decode_u32()?; - let user_name = decoder.decode_string()?; - Ok(Self { token, user_name }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let token = self.decode()?; + let user_name = self.decode()?; + Ok(CannotConnectRequest { token, user_name }) } } @@ -265,12 +266,12 @@ impl ProtoEncode for ConnectToPeerRequest { } } -impl ProtoDecode for ConnectToPeerRequest { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let token = decoder.decode_u32()?; - let user_name = decoder.decode_string()?; - let connection_type = decoder.decode_string()?; - Ok(Self { +impl Decode for T { + fn decode(&mut self) -> io::Result { + let token = self.decode()?; + let user_name = self.decode()?; + let connection_type = self.decode()?; + Ok(ConnectToPeerRequest { token, user_name, connection_type, @@ -303,11 +304,11 @@ impl ProtoEncode for FileSearchRequest { } } -impl ProtoDecode for FileSearchRequest { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let ticket = decoder.decode_u32()?; - let query = decoder.decode_string()?; - Ok(Self { ticket, query }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let ticket = self.decode()?; + let query = self.decode()?; + Ok(FileSearchRequest { ticket, query }) } } @@ -375,14 +376,14 @@ impl ProtoEncode for LoginRequest { } } -impl ProtoDecode for LoginRequest { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let username = decoder.decode_string()?; - let password = decoder.decode_string()?; - let major = decoder.decode_u32()?; - let digest = decoder.decode_string()?; - let minor = decoder.decode_u32()?; - Ok(Self { +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()?; + Ok(LoginRequest { username, password, digest, @@ -414,10 +415,10 @@ impl ProtoEncode for PeerAddressRequest { } } -impl ProtoDecode for PeerAddressRequest { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let username = decoder.decode_string()?; - Ok(Self { username: username }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let username = self.decode()?; + Ok(PeerAddressRequest { username: username }) } } @@ -443,10 +444,10 @@ impl ProtoEncode for RoomJoinRequest { } } -impl ProtoDecode for RoomJoinRequest { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let room_name = decoder.decode_string()?; - Ok(Self { room_name: room_name }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let room_name = self.decode()?; + Ok(RoomJoinRequest { room_name: room_name }) } } @@ -472,10 +473,10 @@ impl ProtoEncode for RoomLeaveRequest { } } -impl ProtoDecode for RoomLeaveRequest { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let room_name = decoder.decode_string()?; - Ok(Self { room_name: room_name }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let room_name = self.decode()?; + Ok(RoomLeaveRequest { room_name: room_name }) } } @@ -504,11 +505,11 @@ impl ProtoEncode for RoomMessageRequest { } } -impl ProtoDecode for RoomMessageRequest { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let room_name = decoder.decode_string()?; - let message = decoder.decode_string()?; - Ok(Self { room_name, message }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let room_name = self.decode()?; + let message = self.decode()?; + Ok(RoomMessageRequest { room_name, message }) } } @@ -534,10 +535,10 @@ impl ProtoEncode for SetListenPortRequest { } } -impl ProtoDecode for SetListenPortRequest { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let port = decoder.decode_u16()?; - Ok(Self { port: port }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let port = self.decode()?; + Ok(SetListenPortRequest { port: port }) } } @@ -563,10 +564,10 @@ impl ProtoEncode for UserStatusRequest { } } -impl ProtoDecode for UserStatusRequest { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let user_name = decoder.decode_string()?; - Ok(Self { user_name: user_name }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let user_name = self.decode()?; + Ok(UserStatusRequest { user_name: user_name }) } } @@ -581,7 +582,7 @@ mod tests { use bytes::BytesMut; - use proto::{ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder}; + use proto::{Decode, ProtoEncode, ProtoEncoder}; use proto::codec::tests::{expect_io_error, roundtrip}; use super::*; @@ -591,8 +592,8 @@ mod tests { let mut bytes = BytesMut::new(); ProtoEncoder::new(&mut bytes).encode_u32(1337).unwrap(); - let mut cursor = io::Cursor::new(bytes); - let result = ServerRequest::decode(&mut ProtoDecoder::new(&mut cursor)); + 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 075a51f..fb97ec3 100644 --- a/src/proto/server/response.rs +++ b/src/proto/server/response.rs @@ -1,8 +1,10 @@ use std::io; use std::net; +use bytes; + use proto::server::constants::*; -use proto::{ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder, User, UserStatus}; +use proto::{Decode, ProtoEncode, ProtoEncoder, User, UserStatus}; use proto::packet::{Packet, PacketReadError, ReadFromPacket}; /*=================* @@ -177,76 +179,76 @@ impl ProtoEncode for ServerResponse { } } -impl ProtoDecode for ServerResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let code = decoder.decode_u32()?; +impl Decode for T { + fn decode(&mut self) -> io::Result { + let code: u32 = self.decode()?; let response = match code { CODE_CONNECT_TO_PEER => { - let response = ConnectToPeerResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::ConnectToPeerResponse(response) } CODE_FILE_SEARCH => { - let response = FileSearchResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::FileSearchResponse(response) } CODE_LOGIN => { - let response = LoginResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::LoginResponse(response) } CODE_PARENT_MIN_SPEED => { - let response = ParentMinSpeedResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::ParentMinSpeedResponse(response) } CODE_PARENT_SPEED_RATIO => { - let response = ParentSpeedRatioResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::ParentSpeedRatioResponse(response) } CODE_PEER_ADDRESS => { - let response = PeerAddressResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::PeerAddressResponse(response) } CODE_PRIVILEGED_USERS => { - let response = PrivilegedUsersResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::PrivilegedUsersResponse(response) } CODE_ROOM_JOIN => { - let response = RoomJoinResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::RoomJoinResponse(response) } CODE_ROOM_LEAVE => { - let response = RoomLeaveResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::RoomLeaveResponse(response) } CODE_ROOM_LIST => { - let response = RoomListResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::RoomListResponse(response) } CODE_ROOM_MESSAGE => { - let response = RoomMessageResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::RoomMessageResponse(response) } CODE_ROOM_TICKERS => { - let response = RoomTickersResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::RoomTickersResponse(response) } CODE_ROOM_USER_JOINED => { - let response = RoomUserJoinedResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::RoomUserJoinedResponse(response) } CODE_ROOM_USER_LEFT => { - let response = RoomUserLeftResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::RoomUserLeftResponse(response) } CODE_USER_INFO => { - let response = UserInfoResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::UserInfoResponse(response) } CODE_USER_STATUS => { - let response = UserStatusResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::UserStatusResponse(response) } CODE_WISHLIST_INTERVAL => { - let response = WishlistIntervalResponse::decode(decoder)?; + let response = self.decode()?; ServerResponse::WishlistIntervalResponse(response) } _ => { @@ -305,14 +307,14 @@ impl ProtoEncode for ConnectToPeerResponse { } } -impl ProtoDecode for ConnectToPeerResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let user_name = decoder.decode_string()?; - let connection_type = decoder.decode_string()?; - let ip = decoder.decode_ipv4_addr()?; - let port = decoder.decode_u16()?; - let token = decoder.decode_u32()?; - let is_privileged = decoder.decode_bool()?; +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()?; Ok(ConnectToPeerResponse { user_name, @@ -358,11 +360,11 @@ impl ProtoEncode for FileSearchResponse { } } -impl ProtoDecode for FileSearchResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let user_name = decoder.decode_string()?; - let ticket = decoder.decode_u32()?; - let query = decoder.decode_string()?; +impl Decode for T { + fn decode(&mut self) -> io::Result { + let user_name = self.decode()?; + let ticket = self.decode()?; + let query = self.decode()?; Ok(FileSearchResponse { user_name, @@ -432,18 +434,19 @@ impl ProtoEncode for LoginResponse { } } -impl ProtoDecode for LoginResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let ok = decoder.decode_bool()?; +impl Decode for T { + fn decode(&mut self) -> io::Result { + let ok: bool = self.decode()?; if !ok { - let reason = decoder.decode_string()?; + let reason = self.decode()?; return Ok(LoginResponse::LoginFail { reason }); } - let motd = decoder.decode_string()?; - let ip = decoder.decode_ipv4_addr()?; + let motd = self.decode()?; + let ip = self.decode()?; - match decoder.decode_bool() { + let result: io::Result = self.decode(); + match result { Ok(value) => debug!("LoginResponse last field: {}", value), Err(e) => debug!("Error reading LoginResponse field: {:?}", e), } @@ -478,10 +481,10 @@ impl ProtoEncode for ParentMinSpeedResponse { } } -impl ProtoDecode for ParentMinSpeedResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let value = decoder.decode_u32()?; - Ok(Self { value }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let value = self.decode()?; + Ok(ParentMinSpeedResponse { value }) } } @@ -507,10 +510,10 @@ impl ProtoEncode for ParentSpeedRatioResponse { } } -impl ProtoDecode for ParentSpeedRatioResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let value = decoder.decode_u32()?; - Ok(Self { value }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let value = self.decode()?; + Ok(ParentSpeedRatioResponse { value }) } } @@ -543,12 +546,12 @@ impl ProtoEncode for PeerAddressResponse { } } -impl ProtoDecode for PeerAddressResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let username = decoder.decode_string()?; - let ip = decoder.decode_ipv4_addr()?; - let port = decoder.decode_u16()?; - Ok(Self { username, ip, port }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let username = self.decode()?; + let ip = self.decode()?; + let port = self.decode()?; + Ok(PeerAddressResponse { username, ip, port }) } } @@ -574,10 +577,10 @@ impl ProtoEncode for PrivilegedUsersResponse { } } -impl ProtoDecode for PrivilegedUsersResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let users = decoder.decode_vec::()?; - Ok(Self { users }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let users = self.decode()?; + Ok(PrivilegedUsersResponse { users }) } } @@ -740,14 +743,14 @@ impl ProtoEncode for UserInfo { } } -impl ProtoDecode for UserInfo { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let average_speed = decoder.decode_u32()?; - let num_downloads = decoder.decode_u32()?; - let unknown = decoder.decode_u32()?; - let num_files = decoder.decode_u32()?; - let num_folders = decoder.decode_u32()?; - Ok(Self { +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()?; + Ok(UserInfo { average_speed, num_downloads, unknown, @@ -816,20 +819,20 @@ fn build_users( users } -impl ProtoDecode for RoomJoinResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let room_name = decoder.decode_string()?; - let user_names = decoder.decode_vec::()?; - let user_statuses = decoder.decode_vec::()?; - let user_infos = decoder.decode_vec::()?; - let user_free_slots = decoder.decode_vec::()?; - let user_countries = decoder.decode_vec::()?; +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()?; let mut owner = None; let mut operators = vec![]; - if decoder.has_remaining() { - owner = Some(decoder.decode_string()?); - operators = decoder.decode_vec::()?; + if self.has_remaining() { + owner = Some(self.decode()?); + operators = self.decode()?; } let users = build_users( @@ -840,7 +843,7 @@ impl ProtoDecode for RoomJoinResponse { user_countries, ); - Ok(Self { + Ok(RoomJoinResponse { room_name, users, owner, @@ -870,10 +873,10 @@ impl ProtoEncode for RoomLeaveResponse { } } -impl ProtoDecode for RoomLeaveResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let room_name = decoder.decode_string()?; - Ok(Self { room_name }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let room_name = self.decode()?; + Ok(RoomLeaveResponse { room_name }) } } @@ -961,9 +964,9 @@ impl RoomListResponse { rooms } - fn decode_rooms(decoder: &mut ProtoDecoder) -> io::Result> { - let room_names = decoder.decode_vec::()?; - let user_counts = decoder.decode_vec::()?; + fn decode_rooms(buf: &mut T) -> io::Result> { + let room_names = buf.decode()?; + let user_counts = buf.decode()?; Ok(Self::build_rooms(room_names, user_counts)) } @@ -990,13 +993,13 @@ impl ProtoEncode for RoomListResponse { } } -impl ProtoDecode for RoomListResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let rooms = Self::decode_rooms(decoder)?; - let owned_private_rooms = Self::decode_rooms(decoder)?; - let other_private_rooms = Self::decode_rooms(decoder)?; - let operated_private_room_names = decoder.decode_vec::()?; - Ok(Self { +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()?; + Ok(RoomListResponse { rooms, owned_private_rooms, other_private_rooms, @@ -1037,12 +1040,12 @@ impl ProtoEncode for RoomMessageResponse { } } -impl ProtoDecode for RoomMessageResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let room_name = decoder.decode_string()?; - let user_name = decoder.decode_string()?; - let message = decoder.decode_string()?; - Ok(Self { +impl Decode for T { + fn decode(&mut self) -> io::Result { + let room_name = self.decode()?; + let user_name = self.decode()?; + let message = self.decode()?; + Ok(RoomMessageResponse { room_name, user_name, message, @@ -1083,11 +1086,11 @@ impl ProtoEncode for RoomTickersResponse { } } -impl ProtoDecode for RoomTickersResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let room_name = decoder.decode_string()?; - let tickers = decoder.decode_vec::<(String, String)>()?; - Ok(Self { room_name, tickers }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let room_name = self.decode()?; + let tickers = self.decode()?; + Ok(RoomTickersResponse { room_name, tickers }) } } @@ -1145,15 +1148,15 @@ impl ProtoEncode for RoomUserJoinedResponse { } } -impl ProtoDecode for RoomUserJoinedResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let room_name = decoder.decode_string()?; - let user_name = decoder.decode_string()?; - let status = UserStatus::decode(decoder)?; - let info = UserInfo::decode(decoder)?; - let num_free_slots = decoder.decode_u32()?; - let country = decoder.decode_string()?; - Ok(Self { +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()?; + Ok(RoomUserJoinedResponse { room_name, user: build_user(user_name, status, info, num_free_slots, country), }) @@ -1188,11 +1191,11 @@ impl ProtoEncode for RoomUserLeftResponse { } } -impl ProtoDecode for RoomUserLeftResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let room_name = decoder.decode_string()?; - let user_name = decoder.decode_string()?; - Ok(Self { +impl Decode for T { + fn decode(&mut self) -> io::Result { + let room_name = self.decode()?; + let user_name = self.decode()?; + Ok(RoomUserLeftResponse { room_name, user_name, }) @@ -1239,14 +1242,14 @@ impl ProtoEncode for UserInfoResponse { } } -impl ProtoDecode for UserInfoResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let user_name = decoder.decode_string()?; - let average_speed = decoder.decode_u32()?; - let num_downloads = decoder.decode_u32()?; - let num_files = decoder.decode_u32()?; - let num_folders = decoder.decode_u32()?; - Ok(Self { +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()?; + Ok(UserInfoResponse { user_name, average_speed: average_speed as usize, num_downloads: num_downloads as usize, @@ -1288,12 +1291,12 @@ impl ProtoEncode for UserStatusResponse { } } -impl ProtoDecode for UserStatusResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let user_name = decoder.decode_string()?; - let status = UserStatus::decode(decoder)?; - let is_privileged = decoder.decode_bool()?; - Ok(Self { +impl Decode for T { + fn decode(&mut self) -> io::Result { + let user_name = self.decode()?; + let status = self.decode()?; + let is_privileged = self.decode()?; + Ok(UserStatusResponse { user_name, status, is_privileged, @@ -1323,10 +1326,10 @@ impl ProtoEncode for WishlistIntervalResponse { } } -impl ProtoDecode for WishlistIntervalResponse { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let seconds = decoder.decode_u32()?; - Ok(Self { seconds }) +impl Decode for T { + fn decode(&mut self) -> io::Result { + let seconds = self.decode()?; + Ok(WishlistIntervalResponse { seconds }) } } @@ -1341,7 +1344,7 @@ mod tests { use bytes::BytesMut; - use proto::{ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder}; + use proto::{Decode, ProtoEncode, ProtoEncoder}; use proto::codec::tests::{expect_io_error, roundtrip}; use super::*; @@ -1351,8 +1354,8 @@ mod tests { let mut bytes = BytesMut::new(); ProtoEncoder::new(&mut bytes).encode_u32(1337).unwrap(); - let mut cursor = io::Cursor::new(bytes); - let result = ServerResponse::decode(&mut ProtoDecoder::new(&mut cursor)); + let result: io::Result = io::Cursor::new(bytes).decode(); + expect_io_error( result, io::ErrorKind::InvalidData, diff --git a/src/proto/transport.rs b/src/proto/transport.rs index c4f67fb..1c1635f 100644 --- a/src/proto/transport.rs +++ b/src/proto/transport.rs @@ -6,7 +6,7 @@ use tokio_io::{AsyncRead, AsyncWrite}; use tokio_io::codec::length_delimited; use proto::peer; -use proto::{ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder, ServerResponse, ServerRequest}; +use proto::{Decode, ProtoEncode, ProtoEncoder, ServerResponse, ServerRequest}; /* ------- * * Helpers * @@ -29,7 +29,7 @@ fn encode_server_request(request: &ServerRequest) -> Result fn decode_peer_message(bytes: BytesMut) -> io::Result { let mut cursor = io::Cursor::new(bytes); - let message = peer::Message::decode(&mut ProtoDecoder::new(&mut cursor))?; + let message = cursor.decode()?; if cursor.has_remaining() { warn!( "Received peer message with trailing bytes. Message:\n{:?}Bytes:{:?}", diff --git a/src/proto/user.rs b/src/proto/user.rs index 762d529..653fd0a 100644 --- a/src/proto/user.rs +++ b/src/proto/user.rs @@ -1,7 +1,9 @@ use std::io; -use proto::{MutPacket, Packet, PacketReadError, ProtoDecode, ProtoDecoder, ProtoEncode, - ProtoEncoder, ReadFromPacket, WriteToPacket}; +use bytes; + +use proto::{Decode, MutPacket, Packet, PacketReadError, ProtoEncode, ProtoEncoder, ReadFromPacket, + WriteToPacket}; const STATUS_OFFLINE: u32 = 1; const STATUS_AWAY: u32 = 2; @@ -53,9 +55,9 @@ impl ProtoEncode for UserStatus { } } -impl ProtoDecode for UserStatus { - fn decode(decoder: &mut ProtoDecoder) -> io::Result { - let value = decoder.decode_u32()?; +impl Decode for T { + fn decode(&mut self) -> io::Result { + let value: u32 = self.decode()?; match value { STATUS_OFFLINE => Ok(UserStatus::Offline), STATUS_AWAY => Ok(UserStatus::Away),