Browse Source

Implement ProtoEncode for RoomJoinResponse.

wip
Titouan Rigoudy 7 years ago
parent
commit
25a3250667
3 changed files with 125 additions and 1 deletions
  1. +14
    -1
      src/proto/codec.rs
  2. +88
    -0
      src/proto/server/response.rs
  3. +23
    -0
      src/user.rs

+ 14
- 1
src/proto/codec.rs View File

@ -308,19 +308,32 @@ impl ProtoDecode for String {
}
}
// 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".
// 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.
impl ProtoEncode for str {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
encoder.encode_string(self)
}
}
// Apparently deref coercion does not work for trait methods.
impl ProtoEncode for String {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
encoder.encode_string(self)
}
}
impl<'a> ProtoEncode for &'a String {
fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> {
encoder.encode_string(*self)
}
}
impl<T: ProtoDecode> ProtoDecode for Vec<T> {
fn decode(decoder: &mut ProtoDecoder) -> Result<Self, DecodeError> {
decoder.decode_vec::<T>()


+ 88
- 0
src/proto/server/response.rs View File

@ -611,6 +611,94 @@ impl RoomJoinResponse {
}
}
// This struct is defined to enable decoding a vector of such values for
// `RoomJoinResponse`, but its data is inlined in the `User` struct.
// For details about individual fields, see said `User` struct.
#[derive(Debug, Eq, PartialEq)]
struct UserInfo {
average_speed: u32,
num_downloads: u32,
unknown: u32,
num_files: u32,
num_folders: u32,
}
impl<'a> From<&'a user::User> for UserInfo {
fn from(user: &'a user::User) -> Self {
Self {
average_speed: user.average_speed as u32,
num_downloads: user.num_downloads as u32,
unknown: user.unknown as u32,
num_files: user.num_files as u32,
num_folders: user.num_folders as u32,
}
}
}
impl ProtoEncode for UserInfo {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
encoder.encode_u32(self.average_speed)?;
encoder.encode_u32(self.num_downloads)?;
encoder.encode_u32(self.unknown)?;
encoder.encode_u32(self.num_files)?;
encoder.encode_u32(self.num_folders)
}
}
impl ProtoDecode for UserInfo {
fn decode(decoder: &mut ProtoDecoder) -> Result<Self, DecodeError> {
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 {
average_speed: average_speed,
num_downloads: num_downloads,
unknown: unknown,
num_files: num_files,
num_folders: num_folders,
})
}
}
impl ProtoEncode for RoomJoinResponse {
fn encode(&self, encoder: &mut ProtoEncoder) -> Result<(), io::Error> {
let mut user_names = vec![];
let mut user_statuses = vec![];
let mut user_infos = vec![];
let mut user_free_slots = vec![];
let mut user_countries = vec![];
for &(ref user_name, ref user) in &self.users {
user_names.push(user_name);
user_statuses.push(user.status);
user_infos.push(UserInfo::from(user));
user_free_slots.push(user.num_free_slots as u32);
user_countries.push(&user.country);
}
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)?;
if let &Some(ref owner) = &self.owner {
encoder.encode_string(owner)?;
encoder.encode_vec(&self.operators)?;
}
Ok(())
}
}
impl ProtoDecode for RoomJoinResponse {
fn decode(decoder: &mut ProtoDecoder) -> Result<Self, DecodeError> {
unimplemented!();
}
}
/*============*
* ROOM LEAVE *
*============*/


+ 23
- 0
src/user.rs View File

@ -44,6 +44,29 @@ impl proto::WriteToPacket for Status {
}
}
impl proto::ProtoEncode for Status {
fn encode(&self, encoder: &mut proto::ProtoEncoder) -> io::Result<()> {
let value = match *self {
Status::Offline => STATUS_OFFLINE,
Status::Away => STATUS_AWAY,
Status::Online => STATUS_ONLINE,
};
encoder.encode_u32(value)
}
}
impl proto::ProtoDecode for Status {
fn decode(decoder: &mut proto::ProtoDecoder) -> Result<Self, proto::DecodeError> {
let value = decoder.decode_u32()?;
match value {
STATUS_OFFLINE => Ok(Status::Offline),
STATUS_AWAY => Ok(Status::Away),
STATUS_ONLINE => Ok(Status::Online),
_ => Err(proto::DecodeError::InvalidUserStatusError(value)),
}
}
}
/// This structure contains the last known information about a fellow user.
/// It does not store the name, as that is stored implicitly as the key in the
/// user hash table.


Loading…
Cancel
Save