Browse Source

Introduce ProtoEncodeError and use it in ProtoEncoder.

Tests are not fixed yet.
wip
Titouan Rigoudy 5 years ago
parent
commit
7bb290f0ef
7 changed files with 148 additions and 104 deletions
  1. +81
    -47
      src/proto/base_codec.rs
  2. +11
    -8
      src/proto/codec.rs
  3. +2
    -1
      src/proto/mod.rs
  4. +3
    -3
      src/proto/peer/message.rs
  5. +14
    -12
      src/proto/server/request.rs
  6. +35
    -31
      src/proto/server/response.rs
  7. +2
    -2
      src/proto/user.rs

+ 81
- 47
src/proto/base_codec.rs View File

@ -299,96 +299,130 @@ impl<T: ProtoDecode> ProtoDecode for Vec<T> {
}
}
#[derive(Debug, Error, PartialEq)]
pub enum ProtoEncodeError {
#[error("encoded string length {length} is too large: {string:?}")]
StringTooLong {
/// The string that is too long to encode.
string: String,
/// The length of `string` in the Windows-1252 encoding.
/// Always larger than `u32::max_value()`.
length: usize,
},
}
impl From<ProtoEncodeError> for io::Error {
fn from(error: ProtoEncodeError) -> Self {
io::Error::new(io::ErrorKind::InvalidData, format!("{}", error))
}
}
/// A type for encoding various types of values into protocol messages.
pub struct ProtoEncoder<'a> {
inner: &'a mut BytesMut,
/// The buffer to which the encoder appends encoded bytes.
buffer: &'a mut Vec<u8>,
}
/// This trait is implemented by types that can be encoded into messages using
/// a `ProtoEncoder`.
pub trait ProtoEncode {
// TODO: Rename to encode_to().
/// Attempts to encode `self` with the given encoder.
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()>;
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError>;
}
impl<'a> ProtoEncoder<'a> {
/// Wraps the given buffer for encoding values into.
///
/// The buffer is grown as required.
pub fn new(inner: &'a mut BytesMut) -> Self {
ProtoEncoder { inner: inner }
/// Encoded bytes are appended. The buffer is not pre-cleared.
pub fn new(buffer: &'a mut Vec<u8>) -> Self {
ProtoEncoder { buffer: buffer }
}
/// Attempts to encode the given u32 value.
pub fn encode_u32(&mut self, val: u32) -> io::Result<()> {
self.inner.reserve(U32_BYTE_LEN);
self.inner.put_u32_le(val);
/// Encodes the given u32 value into the underlying buffer.
pub fn encode_u32(&mut self, val: u32) -> Result<(), ProtoEncodeError> {
self.buffer.extend_from_slice(&val.to_le_bytes());
Ok(())
}
/// Attempts to encode the given boolean value.
pub fn encode_bool(&mut self, val: bool) -> io::Result<()> {
self.inner.reserve(1);
self.inner.put_u8(val as u8);
Ok(())
/// Encodes the given u16 value into the underlying buffer.
pub fn encode_u16(&mut self, val: u16) -> Result<(), ProtoEncodeError> {
self.encode_u32(val as u32)
}
/// Attempts to encode the given IPv4 address.
pub fn encode_ipv4_addr(&mut self, addr: net::Ipv4Addr) -> io::Result<()> {
let mut octets = addr.octets();
octets.reverse(); // Little endian.
self.inner.extend(&octets);
/// Encodes the given boolean value into the underlying buffer.
pub fn encode_bool(&mut self, val: bool) -> Result<(), ProtoEncodeError> {
self.buffer.push(val as u8);
Ok(())
}
/// Attempts to encode the given string.
pub fn encode_string(&mut self, val: &str) -> io::Result<()> {
// Encode the string.
let bytes = match WINDOWS_1252.encode(val, EncoderTrap::Strict) {
Ok(bytes) => bytes,
/// Encodes the given string into the underlying buffer.
pub fn encode_string(&mut self, val: &str) -> Result<(), ProtoEncodeError> {
// Record where we were when we started. This is where we will write
// the length prefix once we are done encoding the string. Until then
// we do not know how many bytes are needed to encode the string.
let prefix_position = self.buffer.len();
self.buffer.extend_from_slice(&[0; U32_BYTE_LEN]);
let string_position = prefix_position + U32_BYTE_LEN;
// Encode the string. We are quite certain this cannot fail because we
// use EncoderTrap::Replace to replace any unencodable characters with
// '?' which is always encodable in Windows-1252.
WINDOWS_1252
.encode_to(val, EncoderTrap::Replace, self.buffer)
.unwrap();
// Calculate the length of the string we just encoded.
let length = self.buffer.len() - string_position;
let length_u32 = match u32::try_from(length) {
Ok(value) => value,
Err(_) => {
return Err(io::Error::new(io::ErrorKind::InvalidData, val.to_string()));
return Err(ProtoEncodeError::StringTooLong {
string: val.to_string(),
length: length,
})
}
};
// Prefix the bytes with the length.
self.encode_u32(bytes.len() as u32)?;
self.inner.extend(bytes);
// Write the length prefix in the space we initially reserved for it.
self.buffer[prefix_position..string_position].copy_from_slice(&length_u32.to_le_bytes());
Ok(())
}
/// Attempts to encode the given value.
/// Encodes the given value into the underlying buffer.
///
/// Allows for easy encoding with type inference:
/// ```
/// let val : Foo = Foo::new(bar);
/// encoder.encode(&val)?;
/// encoder.encode(&Foo::new(bar))?;
/// ```
pub fn encode<T: ProtoEncode>(&mut self, val: &T) -> io::Result<()> {
pub fn encode<T: ProtoEncode>(&mut self, val: &T) -> Result<(), ProtoEncodeError> {
val.encode(self)
}
}
impl ProtoEncode for u32 {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_u32(*self)
}
}
impl ProtoEncode for bool {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
encoder.encode_bool(*self)
impl ProtoEncode for u16 {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_u16(*self)
}
}
impl ProtoEncode for u16 {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
encoder.encode_u32(*self as u32)
impl ProtoEncode for bool {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_bool(*self)
}
}
impl ProtoEncode for net::Ipv4Addr {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
encoder.encode_ipv4_addr(*self)
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_u32(u32::from(*self))
}
}
@ -401,32 +435,32 @@ impl ProtoEncode for net::Ipv4Addr {
// Proto{De,En}code) but it is not really worth the hassle.
impl ProtoEncode for str {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(self)
}
}
impl ProtoEncode for String {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(self)
}
}
impl<'a> ProtoEncode for &'a String {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(*self)
}
}
impl<T: ProtoEncode, U: ProtoEncode> ProtoEncode for (T, U) {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
self.0.encode(encoder)?;
self.1.encode(encoder)
}
}
impl<T: ProtoEncode> ProtoEncode for [T] {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_u32(self.len() as u32)?;
for ref item in self {
item.encode(encoder)?;
@ -436,7 +470,7 @@ impl<T: ProtoEncode> ProtoEncode for [T] {
}
impl<T: ProtoEncode> ProtoEncode for Vec<T> {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
let slice: &[T] = &*self;
slice.encode(encoder)
}


+ 11
- 8
src/proto/codec.rs View File

@ -9,6 +9,8 @@
//! This enables wrapping AsyncRead and AsyncWrite objects into Stream and Sink
//! objects using tokio_codec's FramedRead and FramedWrite adapters.
// TODO: Refactor all this into futures and remove tokio dependency.
use std::io;
use std::marker;
@ -37,18 +39,19 @@ impl<T: ProtoEncode> tokio_codec::Encoder for LengthPrefixedEncoder<T> {
type Error = io::Error;
fn encode(&mut self, item: Self::Item, dst: &mut BytesMut) -> Result<(), Self::Error> {
// Split buffer into two parts: the length prefix and the message.
dst.reserve(U32_BYTE_LEN);
let mut msg_dst = dst.split_off(U32_BYTE_LEN);
// Encode the message.
item.encode(&mut ProtoEncoder::new(&mut msg_dst))?;
// Note that this is ugly right now, but will get better once we switch
// off of Tokio and onto regular futures.
let mut buffer = vec![];
ProtoEncoder::new(&mut buffer).encode(&item)?;
// Encode the message length.
ProtoEncoder::new(dst).encode_u32(msg_dst.len() as u32)?;
let mut prefix = vec![];
ProtoEncoder::new(&mut prefix).encode_u32(buffer.len() as u32)?;
// Reassemble both parts into one contiguous buffer.
dst.unsplit(msg_dst);
dst.reserve(prefix.len() + buffer.len());
dst.extend_from_slice(&prefix);
dst.extend_from_slice(&buffer);
Ok(())
}
}


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

@ -9,7 +9,8 @@ mod stream;
mod user;
pub use self::base_codec::{
Decode, ProtoDecode, ProtoDecodeError, ProtoDecoder, ProtoEncode, ProtoEncoder,
Decode, ProtoDecode, ProtoDecodeError, ProtoDecoder, ProtoEncode, ProtoEncodeError,
ProtoEncoder,
};
pub use self::codec::*;
pub use self::handler::*;


+ 3
- 3
src/proto/peer/message.rs View File

@ -3,7 +3,7 @@ use std::io;
use crate::proto::peer::constants::*;
use crate::proto::{
MutPacket, Packet, PacketReadError, ProtoDecode, ProtoDecodeError, ProtoDecoder, ProtoEncode,
ProtoEncoder, ReadFromPacket, WriteToPacket,
ProtoEncodeError, ProtoEncoder, ReadFromPacket, WriteToPacket,
};
/*=========*
@ -67,7 +67,7 @@ impl ProtoDecode for Message {
}
impl ProtoEncode for Message {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
match *self {
Message::PierceFirewall(token) => {
encoder.encode_u32(CODE_PIERCE_FIREWALL)?;
@ -132,7 +132,7 @@ impl WriteToPacket for PeerInit {
}
impl ProtoEncode for PeerInit {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.user_name)?;
encoder.encode_string(&self.connection_type)?;
encoder.encode_u32(self.token)?;


+ 14
- 12
src/proto/server/request.rs View File

@ -5,7 +5,9 @@ use crypto::md5::Md5;
use crate::proto::packet::{MutPacket, WriteToPacket};
use crate::proto::server::constants::*;
use crate::proto::{ProtoDecode, ProtoDecodeError, ProtoDecoder, ProtoEncode, ProtoEncoder};
use crate::proto::{
ProtoDecode, ProtoDecodeError, ProtoDecoder, ProtoEncode, ProtoEncodeError, ProtoEncoder,
};
/* ------- *
* Helpers *
@ -98,7 +100,7 @@ impl WriteToPacket for ServerRequest {
}
impl ProtoEncode for ServerRequest {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
match *self {
ServerRequest::CannotConnectRequest(ref request) => {
encoder.encode_u32(CODE_CANNOT_CONNECT)?;
@ -225,7 +227,7 @@ impl WriteToPacket for CannotConnectRequest {
}
impl ProtoEncode for CannotConnectRequest {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_u32(self.token)?;
encoder.encode_string(&self.user_name)
}
@ -260,7 +262,7 @@ impl WriteToPacket for ConnectToPeerRequest {
}
impl ProtoEncode for ConnectToPeerRequest {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_u32(self.token)?;
encoder.encode_string(&self.user_name)?;
encoder.encode_string(&self.connection_type)
@ -299,7 +301,7 @@ impl WriteToPacket for FileSearchRequest {
}
impl ProtoEncode for FileSearchRequest {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_u32(self.ticket)?;
encoder.encode_string(&self.query)
}
@ -368,7 +370,7 @@ impl WriteToPacket for LoginRequest {
}
impl ProtoEncode for LoginRequest {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.username)?;
encoder.encode_string(&self.password)?;
encoder.encode_u32(self.major)?;
@ -411,7 +413,7 @@ impl WriteToPacket for PeerAddressRequest {
}
impl ProtoEncode for PeerAddressRequest {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.username)
}
}
@ -440,7 +442,7 @@ impl WriteToPacket for RoomJoinRequest {
}
impl ProtoEncode for RoomJoinRequest {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.room_name)
}
}
@ -471,7 +473,7 @@ impl WriteToPacket for RoomLeaveRequest {
}
impl ProtoEncode for RoomLeaveRequest {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.room_name)
}
}
@ -504,7 +506,7 @@ impl WriteToPacket for RoomMessageRequest {
}
impl ProtoEncode for RoomMessageRequest {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.room_name)?;
encoder.encode_string(&self.message)
}
@ -535,7 +537,7 @@ impl WriteToPacket for SetListenPortRequest {
}
impl ProtoEncode for SetListenPortRequest {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode(&self.port)
}
}
@ -564,7 +566,7 @@ impl WriteToPacket for UserStatusRequest {
}
impl ProtoEncode for UserStatusRequest {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.user_name)
}
}


+ 35
- 31
src/proto/server/response.rs View File

@ -4,7 +4,8 @@ use std::net;
use crate::proto::packet::{Packet, PacketReadError, ReadFromPacket};
use crate::proto::server::constants::*;
use crate::proto::{
ProtoDecode, ProtoDecodeError, ProtoDecoder, ProtoEncode, ProtoEncoder, User, UserStatus,
ProtoDecode, ProtoDecodeError, ProtoDecoder, ProtoEncode, ProtoEncodeError, ProtoEncoder, User,
UserStatus,
};
/*=================*
@ -92,7 +93,7 @@ impl ReadFromPacket for ServerResponse {
}
impl ProtoEncode for ServerResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
match *self {
ServerResponse::ConnectToPeerResponse(ref response) => {
encoder.encode_u32(CODE_CONNECT_TO_PEER)?;
@ -290,11 +291,11 @@ impl ReadFromPacket for ConnectToPeerResponse {
}
impl ProtoEncode for ConnectToPeerResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
encoder.encode_string(&self.user_name)?;
encoder.encode_string(&self.connection_type)?;
encoder.encode_ipv4_addr(self.ip)?;
encoder.encode(&self.port)?;
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode(&self.user_name)?;
encoder.encode(&self.connection_type)?;
encoder.encode(&self.ip)?;
encoder.encode_u16(self.port)?;
encoder.encode_u32(self.token)?;
encoder.encode_bool(self.is_privileged)
}
@ -346,7 +347,7 @@ impl ReadFromPacket for FileSearchResponse {
}
impl ProtoEncode for FileSearchResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.user_name)?;
encoder.encode_u32(self.ticket)?;
encoder.encode_string(&self.query)
@ -409,7 +410,7 @@ impl ReadFromPacket for LoginResponse {
}
impl ProtoEncode for LoginResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
match *self {
LoginResponse::LoginOk {
ref motd,
@ -417,12 +418,12 @@ impl ProtoEncode for LoginResponse {
password_md5_opt: _,
} => {
encoder.encode_bool(true)?;
encoder.encode_string(motd)?;
encoder.encode_ipv4_addr(ip)?;
encoder.encode(motd)?;
encoder.encode(&ip)?;
}
LoginResponse::LoginFail { ref reason } => {
encoder.encode_bool(false)?;
encoder.encode_string(reason)?;
encoder.encode(reason)?;
}
};
Ok(())
@ -471,7 +472,7 @@ impl ReadFromPacket for ParentMinSpeedResponse {
}
impl ProtoEncode for ParentMinSpeedResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_u32(self.value)
}
}
@ -500,7 +501,7 @@ impl ReadFromPacket for ParentSpeedRatioResponse {
}
impl ProtoEncode for ParentSpeedRatioResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_u32(self.value)
}
}
@ -534,10 +535,10 @@ impl ReadFromPacket for PeerAddressResponse {
}
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(&self.port)
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode(&self.username)?;
encoder.encode(&self.ip)?;
encoder.encode_u16(self.port)
}
}
@ -567,7 +568,7 @@ impl ReadFromPacket for PrivilegedUsersResponse {
}
impl ProtoEncode for PrivilegedUsersResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode(&self.users)
}
}
@ -727,7 +728,7 @@ fn build_user(
}
impl ProtoEncode for UserInfo {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_u32(self.average_speed)?;
encoder.encode_u32(self.num_downloads)?;
encoder.encode_u32(self.unknown)?;
@ -754,7 +755,7 @@ impl ProtoDecode for UserInfo {
}
impl ProtoEncode for RoomJoinResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
let mut user_names = vec![];
let mut user_statuses = vec![];
let mut user_infos = vec![];
@ -863,7 +864,7 @@ impl ReadFromPacket for RoomLeaveResponse {
}
impl ProtoEncode for RoomLeaveResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.room_name)
}
}
@ -964,7 +965,10 @@ impl RoomListResponse {
Ok(Self::build_rooms(room_names, user_counts))
}
fn encode_rooms(rooms: &[(String, u32)], encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode_rooms(
rooms: &[(String, u32)],
encoder: &mut ProtoEncoder,
) -> Result<(), ProtoEncodeError> {
let mut room_names = vec![];
let mut user_counts = vec![];
@ -979,7 +983,7 @@ impl RoomListResponse {
}
impl ProtoEncode for RoomListResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
Self::encode_rooms(&self.rooms, encoder)?;
Self::encode_rooms(&self.owned_private_rooms, encoder)?;
Self::encode_rooms(&self.other_private_rooms, encoder)?;
@ -1027,7 +1031,7 @@ impl ReadFromPacket for RoomMessageResponse {
}
impl ProtoEncode for RoomMessageResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.room_name)?;
encoder.encode_string(&self.user_name)?;
encoder.encode_string(&self.message)
@ -1074,7 +1078,7 @@ impl ReadFromPacket for RoomTickersResponse {
}
impl ProtoEncode for RoomTickersResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.room_name)?;
encoder.encode(&self.tickers)
}
@ -1132,7 +1136,7 @@ impl ReadFromPacket for RoomUserJoinedResponse {
}
impl ProtoEncode for RoomUserJoinedResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.room_name)?;
encoder.encode_string(&self.user.name)?;
self.user.status.encode(encoder)?;
@ -1179,7 +1183,7 @@ impl ReadFromPacket for RoomUserLeftResponse {
}
impl ProtoEncode for RoomUserLeftResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.room_name)?;
encoder.encode_string(&self.user_name)
}
@ -1227,7 +1231,7 @@ impl ReadFromPacket for UserInfoResponse {
}
impl ProtoEncode for UserInfoResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.user_name)?;
encoder.encode_u32(self.average_speed as u32)?;
encoder.encode_u32(self.num_downloads as u32)?;
@ -1278,7 +1282,7 @@ impl ReadFromPacket for UserStatusResponse {
}
impl ProtoEncode for UserStatusResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_string(&self.user_name)?;
self.status.encode(encoder)?;
encoder.encode_bool(self.is_privileged)
@ -1315,7 +1319,7 @@ impl ReadFromPacket for WishlistIntervalResponse {
}
impl ProtoEncode for WishlistIntervalResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
encoder.encode_u32(self.seconds)
}
}


+ 2
- 2
src/proto/user.rs View File

@ -2,7 +2,7 @@ use std::io;
use crate::proto::{
MutPacket, Packet, PacketReadError, ProtoDecode, ProtoDecodeError, ProtoDecoder, ProtoEncode,
ProtoEncoder, ReadFromPacket, WriteToPacket,
ProtoEncodeError, ProtoEncoder, ReadFromPacket, WriteToPacket,
};
const STATUS_OFFLINE: u32 = 1;
@ -45,7 +45,7 @@ impl WriteToPacket for UserStatus {
}
impl ProtoEncode for UserStatus {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), ProtoEncodeError> {
let value = match *self {
UserStatus::Offline => STATUS_OFFLINE,
UserStatus::Away => STATUS_AWAY,


Loading…
Cancel
Save