Browse Source

Introduce ProtoDecoder instead of extending Buf trait.

wip
Titouan Rigoudy 7 years ago
parent
commit
c48673c390
8 changed files with 414 additions and 390 deletions
  1. +189
    -151
      src/proto/base_codec.rs
  2. +4
    -8
      src/proto/handler.rs
  3. +1
    -1
      src/proto/mod.rs
  4. +14
    -17
      src/proto/peer/message.rs
  5. +58
    -59
      src/proto/server/request.rs
  6. +137
    -140
      src/proto/server/response.rs
  7. +7
    -8
      src/proto/transport.rs
  8. +4
    -6
      src/proto/user.rs

+ 189
- 151
src/proto/base_codec.rs View File

@ -56,41 +56,89 @@ fn invalid_data_error<T: fmt::Debug>(type_name: &str, value: T) -> io::Error {
)
}
// A few helper methods for implementing Decode<T> 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<u32>;
/// 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<Self>;
}
impl<T: Buf> 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<u32> {
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<bool> {
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<String> {
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<T: ProtoDecode>(&mut self) -> io::Result<T> {
T::decode_from(self)
}
}
impl<T: Buf> Decode<u32> for T {
fn decode(&mut self) -> io::Result<u32> {
self.decode_u32_generic("u32")
impl ProtoDecode for u32 {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
decoder.decode_u32_generic("u32")
}
}
impl<T: Buf> Decode<u16> for T {
fn decode(&mut self) -> io::Result<u16> {
let n = self.decode_u32_generic("u16")?;
impl ProtoDecode for u16 {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
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<T: Buf> Decode<u16> for T {
}
}
impl<T: Buf> Decode<bool> for T {
fn decode(&mut self) -> io::Result<bool> {
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<Self> {
decoder.decode_bool()
}
}
impl<T: Buf> Decode<net::Ipv4Addr> for T {
fn decode(&mut self) -> io::Result<net::Ipv4Addr> {
let ip = self.decode_u32_generic("ipv4 address")?;
impl ProtoDecode for net::Ipv4Addr {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
let ip = decoder.decode_u32_generic("ipv4 address")?;
Ok(net::Ipv4Addr::from(ip))
}
}
impl<T: Buf> Decode<String> for T {
fn decode(&mut self) -> io::Result<String> {
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<Self> {
decoder.decode_string()
}
}
impl<T, U, V> Decode<(U, V)> for T
where
T: Decode<U> + Decode<V>,
impl<T: ProtoDecode, U: ProtoDecode> 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<Self> {
let first = decoder.decode()?;
let second = decoder.decode()?;
Ok((first, second))
}
}
impl<T, U> Decode<Vec<U>> for T
where
T: BootstrapDecode + Decode<U>,
impl<T: ProtoDecode> ProtoDecode for Vec<T>
{
fn decode(&mut self) -> io::Result<Vec<U>> {
let len = self.decode_u32_generic("vector length")? as usize;
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
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<T> 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<T, U>(&mut self, pair: &(T, U)) -> io::Result<()>
where
T: ProtoEncode,
U: ProtoEncode,
{
pair.0.encode(self)?;
pair.1.encode(self)
}
pub fn encode_vec<T: ProtoEncode>(&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<T: ProtoEncode>(&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<str> 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<str>` for
// type `bool` in future versions".
// It would be nice to use AsRef<str>, or Deref<Target=str> 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<str>` 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<T: ProtoEncode, U: ProtoEncode> 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<T: ProtoEncode> ProtoEncode for Vec<T> {
impl<T: ProtoEncode> 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<T: ProtoEncode> ProtoEncode for Vec<T> {
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<T>(input: T)
where
T: fmt::Debug + Eq + PartialEq + ProtoEncode,
io::Cursor<BytesMut>: Decode<T>,
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::<T>().unwrap();
assert_eq!(output, input);
}
@ -364,11 +370,6 @@ pub mod tests {
}
}
// Helper for succinctness in tests below.
fn new_cursor(vec: Vec<u8>) -> io::Cursor<BytesMut> {
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::<u32>().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<u32> = new_cursor(vec![13]).decode();
let buffer = BytesMut::from(vec![13]);
let mut decoder = ProtoDecoder::new(&buffer);
let result = decoder.decode::<u32>();
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::<bool>().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::<bool>().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<bool> = new_cursor(vec![42]).decode();
let buffer = BytesMut::from(vec![42]);
let result = ProtoDecoder::new(&buffer).decode::<bool>();
expect_io_error(result, io::ErrorKind::InvalidData, "invalid bool: 42");
}
#[test]
fn decode_bool_unexpected_eof() {
let result: io::Result<bool> = new_cursor(vec![]).decode();
let buffer = BytesMut::new();
let result = ProtoDecoder::new(&buffer).decode::<bool>();
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::<u16>().unwrap();
assert_eq!(val, expected_val as u16);
assert_eq!(cursor.remaining(), 0);
assert_eq!(decoder.bytes(), EMPTY_BYTES);
} else {
let result: io::Result<u16> = cursor.decode();
expect_io_error(
result,
decoder.decode::<u16>(),
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<u16> = new_cursor(vec![]).decode();
let buffer = BytesMut::new();
let mut decoder = ProtoDecoder::new(&buffer);
let result = decoder.decode::<u16>();
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::<net::Ipv4Addr>().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::<String>().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<u32> = cursor.decode().unwrap();
let buffer = BytesMut::from(bytes);
let mut decoder = ProtoDecoder::new(&buffer);
let vec = decoder.decode::<Vec<u32>>().unwrap();
assert_eq!(vec, expected_vec);
assert_eq!(cursor.remaining(), 0);
assert_eq!(decoder.bytes(), EMPTY_BYTES);
}
#[test]


+ 4
- 8
src/proto/handler.rs View File

@ -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) => {


+ 1
- 1
src/proto/mod.rs View File

@ -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::*;


+ 14
- 17
src/proto/peer/message.rs View File

@ -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<T: bytes::Buf> Decode<Message> for T {
fn decode(&mut self) -> io::Result<Message> {
let code: u32 = self.decode()?;
impl ProtoDecode for Message {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
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<T: bytes::Buf> Decode<PeerInit> for T {
fn decode(&mut self) -> io::Result<PeerInit> {
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<Self> {
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<Message> = io::Cursor::new(bytes).decode();
let result = ProtoDecoder::new(&bytes).decode::<Message>();
expect_io_error(
result,


+ 58
- 59
src/proto/server/request.rs View File

@ -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<T: bytes::Buf> Decode<ServerRequest> for T {
fn decode(&mut self) -> io::Result<ServerRequest> {
let code: u32 = self.decode()?;
impl ProtoDecode for ServerRequest {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
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<T: bytes::Buf> Decode<CannotConnectRequest> for T {
fn decode(&mut self) -> io::Result<CannotConnectRequest> {
let token = self.decode()?;
let user_name = self.decode()?;
impl ProtoDecode for CannotConnectRequest {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
let token = decoder.decode()?;
let user_name = decoder.decode()?;
Ok(CannotConnectRequest { token, user_name })
}
}
@ -266,11 +265,11 @@ impl ProtoEncode for ConnectToPeerRequest {
}
}
impl<T: bytes::Buf> Decode<ConnectToPeerRequest> for T {
fn decode(&mut self) -> io::Result<ConnectToPeerRequest> {
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<Self> {
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<T: bytes::Buf> Decode<FileSearchRequest> for T {
fn decode(&mut self) -> io::Result<FileSearchRequest> {
let ticket = self.decode()?;
let query = self.decode()?;
impl ProtoDecode for FileSearchRequest {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
let ticket = decoder.decode()?;
let query = decoder.decode()?;
Ok(FileSearchRequest { ticket, query })
}
}
@ -376,13 +375,13 @@ impl ProtoEncode for LoginRequest {
}
}
impl<T: bytes::Buf> Decode<LoginRequest> for T {
fn decode(&mut self) -> io::Result<LoginRequest> {
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<Self> {
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<T: bytes::Buf> Decode<PeerAddressRequest> for T {
fn decode(&mut self) -> io::Result<PeerAddressRequest> {
let username = self.decode()?;
impl ProtoDecode for PeerAddressRequest {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
let username = decoder.decode()?;
Ok(PeerAddressRequest { username: username })
}
}
@ -444,9 +443,9 @@ impl ProtoEncode for RoomJoinRequest {
}
}
impl<T: bytes::Buf> Decode<RoomJoinRequest> for T {
fn decode(&mut self) -> io::Result<RoomJoinRequest> {
let room_name = self.decode()?;
impl ProtoDecode for RoomJoinRequest {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
let room_name = decoder.decode()?;
Ok(RoomJoinRequest {
room_name: room_name,
})
@ -475,9 +474,9 @@ impl ProtoEncode for RoomLeaveRequest {
}
}
impl<T: bytes::Buf> Decode<RoomLeaveRequest> for T {
fn decode(&mut self) -> io::Result<RoomLeaveRequest> {
let room_name = self.decode()?;
impl ProtoDecode for RoomLeaveRequest {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
let room_name = decoder.decode()?;
Ok(RoomLeaveRequest {
room_name: room_name,
})
@ -509,10 +508,10 @@ impl ProtoEncode for RoomMessageRequest {
}
}
impl<T: bytes::Buf> Decode<RoomMessageRequest> for T {
fn decode(&mut self) -> io::Result<RoomMessageRequest> {
let room_name = self.decode()?;
let message = self.decode()?;
impl ProtoDecode for RoomMessageRequest {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
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<T: bytes::Buf> Decode<SetListenPortRequest> for T {
fn decode(&mut self) -> io::Result<SetListenPortRequest> {
let port = self.decode()?;
impl ProtoDecode for SetListenPortRequest {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
let port = decoder.decode()?;
Ok(SetListenPortRequest { port: port })
}
}
@ -568,9 +567,9 @@ impl ProtoEncode for UserStatusRequest {
}
}
impl<T: bytes::Buf> Decode<UserStatusRequest> for T {
fn decode(&mut self) -> io::Result<UserStatusRequest> {
let user_name = self.decode()?;
impl ProtoDecode for UserStatusRequest {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
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::<ServerRequest>();
let result: io::Result<ServerRequest> = io::Cursor::new(bytes).decode();
expect_io_error(
result,
io::ErrorKind::InvalidData,


+ 137
- 140
src/proto/server/response.rs View File

@ -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<T: bytes::Buf> Decode<ServerResponse> for T {
fn decode(&mut self) -> io::Result<ServerResponse> {
let code: u32 = self.decode()?;
impl ProtoDecode for ServerResponse {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
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<T: bytes::Buf> Decode<ConnectToPeerResponse> for T {
fn decode(&mut self) -> io::Result<ConnectToPeerResponse> {
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<Self> {
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<T: bytes::Buf> Decode<FileSearchResponse> for T {
fn decode(&mut self) -> io::Result<FileSearchResponse> {
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<Self> {
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<T: bytes::Buf> Decode<LoginResponse> for T {
fn decode(&mut self) -> io::Result<LoginResponse> {
let ok: bool = self.decode()?;
impl ProtoDecode for LoginResponse {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
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<bool> = self.decode();
let result: io::Result<bool> = 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<T: bytes::Buf> Decode<ParentMinSpeedResponse> for T {
fn decode(&mut self) -> io::Result<ParentMinSpeedResponse> {
let value = self.decode()?;
impl ProtoDecode for ParentMinSpeedResponse {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
let value = decoder.decode()?;
Ok(ParentMinSpeedResponse { value })
}
}
@ -511,9 +509,9 @@ impl ProtoEncode for ParentSpeedRatioResponse {
}
}
impl<T: bytes::Buf> Decode<ParentSpeedRatioResponse> for T {
fn decode(&mut self) -> io::Result<ParentSpeedRatioResponse> {
let value = self.decode()?;
impl ProtoDecode for ParentSpeedRatioResponse {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
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<T: bytes::Buf> Decode<PeerAddressResponse> for T {
fn decode(&mut self) -> io::Result<PeerAddressResponse> {
let username = self.decode()?;
let ip = self.decode()?;
let port = self.decode()?;
impl ProtoDecode for PeerAddressResponse {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
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<T: bytes::Buf> Decode<PrivilegedUsersResponse> for T {
fn decode(&mut self) -> io::Result<PrivilegedUsersResponse> {
let users = self.decode()?;
impl ProtoDecode for PrivilegedUsersResponse {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
let users = decoder.decode()?;
Ok(PrivilegedUsersResponse { users })
}
}
@ -742,13 +740,13 @@ impl ProtoEncode for UserInfo {
}
}
impl<T: bytes::Buf> Decode<UserInfo> for T {
fn decode(&mut self) -> io::Result<UserInfo> {
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<Self> {
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<T: bytes::Buf> Decode<RoomJoinResponse> for T {
fn decode(&mut self) -> io::Result<RoomJoinResponse> {
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<Self> {
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<T: bytes::Buf> Decode<RoomLeaveResponse> for T {
fn decode(&mut self) -> io::Result<RoomLeaveResponse> {
let room_name = self.decode()?;
impl ProtoDecode for RoomLeaveResponse {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
let room_name = decoder.decode()?;
Ok(RoomLeaveResponse { room_name })
}
}
@ -964,9 +962,9 @@ impl RoomListResponse {
rooms
}
fn decode_rooms<T: bytes::Buf>(buf: &mut T) -> io::Result<Vec<(String, u32)>> {
let room_names = buf.decode()?;
let user_counts = buf.decode()?;
fn decode_rooms(decoder: &mut ProtoDecoder) -> io::Result<Vec<(String, u32)>> {
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<T: bytes::Buf> Decode<RoomListResponse> for T {
fn decode(&mut self) -> io::Result<RoomListResponse> {
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<Self> {
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<T: bytes::Buf> Decode<RoomMessageResponse> for T {
fn decode(&mut self) -> io::Result<RoomMessageResponse> {
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<Self> {
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<T: bytes::Buf> Decode<RoomTickersResponse> for T {
fn decode(&mut self) -> io::Result<RoomTickersResponse> {
let room_name = self.decode()?;
let tickers = self.decode()?;
impl ProtoDecode for RoomTickersResponse {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
let room_name = decoder.decode()?;
let tickers = decoder.decode()?;
Ok(RoomTickersResponse { room_name, tickers })
}
}
@ -1148,14 +1146,14 @@ impl ProtoEncode for RoomUserJoinedResponse {
}
}
impl<T: bytes::Buf> Decode<RoomUserJoinedResponse> for T {
fn decode(&mut self) -> io::Result<RoomUserJoinedResponse> {
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<Self> {
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<T: bytes::Buf> Decode<RoomUserLeftResponse> for T {
fn decode(&mut self) -> io::Result<RoomUserLeftResponse> {
let room_name = self.decode()?;
let user_name = self.decode()?;
impl ProtoDecode for RoomUserLeftResponse {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
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<T: bytes::Buf> Decode<UserInfoResponse> for T {
fn decode(&mut self) -> io::Result<UserInfoResponse> {
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<Self> {
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<T: bytes::Buf> Decode<UserStatusResponse> for T {
fn decode(&mut self) -> io::Result<UserStatusResponse> {
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<Self> {
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<T: bytes::Buf> Decode<WishlistIntervalResponse> for T {
fn decode(&mut self) -> io::Result<WishlistIntervalResponse> {
let seconds = self.decode()?;
impl ProtoDecode for WishlistIntervalResponse {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
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<ServerResponse> = io::Cursor::new(bytes).decode();
let result = ProtoDecoder::new(&bytes).decode::<ServerResponse>();
expect_io_error(
result,


+ 7
- 8
src/proto/transport.rs View File

@ -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<T>
where
T: fmt::Debug,
io::Cursor<&'a mut BytesMut>: Decode<T>,
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)


+ 4
- 6
src/proto/user.rs View File

@ -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<T: bytes::Buf> Decode<UserStatus> for T {
fn decode(&mut self) -> io::Result<UserStatus> {
let value: u32 = self.decode()?;
impl ProtoDecode for UserStatus {
fn decode_from(decoder: &mut ProtoDecoder) -> io::Result<Self> {
let value: u32 = decoder.decode()?;
match value {
STATUS_OFFLINE => Ok(UserStatus::Offline),
STATUS_AWAY => Ok(UserStatus::Away),


Loading…
Cancel
Save