From 7008d6eee93b598b3a5cc4b58cf00aa2d5b6ad64 Mon Sep 17 00:00:00 2001 From: Titouan Rigoudy Date: Sat, 6 Jan 2018 10:28:28 -0500 Subject: [PATCH] Move User struct to proto module. --- src/control/response.rs | 6 +-- src/proto/mod.rs | 6 ++- src/proto/server/response.rs | 43 ++++++++-------- src/proto/user.rs | 86 +++++++++++++++++++++++++++++++ src/room.rs | 5 +- src/user.rs | 99 ++---------------------------------- 6 files changed, 121 insertions(+), 124 deletions(-) create mode 100644 src/proto/user.rs diff --git a/src/control/response.rs b/src/control/response.rs index 1b133c3..db16386 100644 --- a/src/control/response.rs +++ b/src/control/response.rs @@ -1,5 +1,5 @@ +use proto::User; use room; -use user; /// This enumeration is the list of possible control responses from the client /// to the controller. @@ -92,11 +92,11 @@ pub struct RoomUserLeftResponse { #[derive(Debug, RustcDecodable, RustcEncodable)] pub struct UserInfoResponse { pub user_name: String, - pub user_info: user::User, + pub user_info: User, } /// This stuct contains the last known information about every user. #[derive(Debug, RustcDecodable, RustcEncodable)] pub struct UserListResponse { - pub user_list: Vec<(String, user::User)>, + pub user_list: Vec<(String, User)>, } diff --git a/src/proto/mod.rs b/src/proto/mod.rs index 97198d1..1b42ccc 100644 --- a/src/proto/mod.rs +++ b/src/proto/mod.rs @@ -1,15 +1,17 @@ +mod codec; mod constants; mod handler; mod packet; pub mod peer; pub mod server; mod stream; -mod codec; mod transport; +mod user; +pub use self::codec::{DecodeError, ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder}; pub use self::handler::*; pub use self::packet::*; pub use self::stream::*; pub use self::server::{ServerResponse, ServerRequest}; pub use self::transport::{PeerTransport, ServerTransport}; -pub use self::codec::{DecodeError, ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder}; +pub use self::user::{User, UserStatus}; diff --git a/src/proto/server/response.rs b/src/proto/server/response.rs index 4ae1030..1353f99 100644 --- a/src/proto/server/response.rs +++ b/src/proto/server/response.rs @@ -2,9 +2,8 @@ use std::io; use std::net; use proto::server::constants::*; -use proto::{DecodeError, ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder}; +use proto::{DecodeError, ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder, User, UserStatus}; use proto::packet::{Packet, PacketReadError, ReadFromPacket}; -use user; /*=================* * SERVER RESPONSE * @@ -522,7 +521,7 @@ impl ProtoDecode for PrivilegedUsersResponse { #[derive(Debug, Eq, PartialEq)] pub struct RoomJoinResponse { pub room_name: String, - pub users: Vec<(String, user::User)>, + pub users: Vec<(String, User)>, pub owner: Option, pub operators: Vec, } @@ -538,9 +537,9 @@ impl ReadFromPacket for RoomJoinResponse { let num_users: usize = try!(packet.read_value()); for _ in 0..num_users { - let name = try!(packet.read_value()); - let user = user::User { - status: user::Status::Offline, + let name : String = try!(packet.read_value()); + let user = User { + status: UserStatus::Offline, average_speed: 0, num_downloads: 0, unknown: 0, @@ -631,8 +630,8 @@ struct UserInfo { num_folders: u32, } -impl<'a> From<&'a user::User> for UserInfo { - fn from(user: &'a user::User) -> Self { +impl UserInfo { + fn from_user(user: &User) -> Self { Self { average_speed: user.average_speed as u32, num_downloads: user.num_downloads as u32, @@ -680,7 +679,7 @@ impl ProtoEncode for RoomJoinResponse { 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_infos.push(UserInfo::from_user(user)); user_free_slots.push(user.num_free_slots as u32); user_countries.push(&user.country); } @@ -703,11 +702,11 @@ impl ProtoEncode for RoomJoinResponse { fn build_users( mut names: Vec, - mut statuses: Vec, + mut statuses: Vec, mut infos: Vec, mut free_slots: Vec, mut countries: Vec, -) -> Vec<(String, user::User)> { +) -> Vec<(String, User)> { let mut users = vec![]; loop { @@ -721,7 +720,7 @@ fn build_users( (Some(name), Some(status), Some(info), Some(slots), Some(country)) => { users.push(( name, - user::User { + User { status: status, average_speed: info.average_speed as usize, num_downloads: info.num_downloads as usize, @@ -730,7 +729,7 @@ fn build_users( num_folders: info.num_folders as usize, num_free_slots: slots as usize, country: country, - }, + } )) } _ => break, @@ -745,7 +744,7 @@ impl ProtoDecode for RoomJoinResponse { fn decode(decoder: &mut ProtoDecoder) -> Result { let room_name = decoder.decode_string()?; let user_names = decoder.decode_vec::()?; - let user_statuses = 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::()?; @@ -905,13 +904,13 @@ impl ReadFromPacket for RoomTickersResponse { pub struct RoomUserJoinedResponse { pub room_name: String, pub user_name: String, - pub user: user::User, + pub user: User, } impl ReadFromPacket for RoomUserJoinedResponse { fn read_from_packet(packet: &mut Packet) -> Result { let room_name = try!(packet.read_value()); - let user_name = try!(packet.read_value()); + let user_name : String = try!(packet.read_value()); let status = try!(packet.read_value()); @@ -927,7 +926,7 @@ impl ReadFromPacket for RoomUserJoinedResponse { Ok(RoomUserJoinedResponse { room_name: room_name, user_name: user_name, - user: user::User { + user: User { status: status, average_speed: average_speed, num_downloads: num_downloads, @@ -999,7 +998,7 @@ impl ReadFromPacket for UserInfoResponse { #[derive(Debug, Eq, PartialEq)] pub struct UserStatusResponse { pub user_name: String, - pub status: user::Status, + pub status: UserStatus, pub is_privileged: bool, } @@ -1131,8 +1130,8 @@ mod tests { users: vec![ ( "alice".to_string(), - user::User { - status: user::Status::Online, + User { + status: UserStatus::Online, average_speed: 1000, num_downloads: 1001, unknown: 1002, @@ -1144,8 +1143,8 @@ mod tests { ), ( "barbara".to_string(), - user::User { - status: user::Status::Away, + User { + status: UserStatus::Away, average_speed: 2000, num_downloads: 2001, unknown: 2002, diff --git a/src/proto/user.rs b/src/proto/user.rs new file mode 100644 index 0000000..b6c340e --- /dev/null +++ b/src/proto/user.rs @@ -0,0 +1,86 @@ +use std::io; + +use proto::{DecodeError, MutPacket, Packet, PacketReadError, ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder, ReadFromPacket, WriteToPacket}; + +const STATUS_OFFLINE: u32 = 1; +const STATUS_AWAY: u32 = 2; +const STATUS_ONLINE: u32 = 3; + +/// This enumeration is the list of possible user statuses. +#[derive(Clone, Copy, Debug, Eq, PartialEq, RustcDecodable, RustcEncodable)] +pub enum UserStatus { + /// The user if offline. + Offline, + /// The user is connected, but AFK. + Away, + /// The user is present. + Online, +} + +impl ReadFromPacket for UserStatus { + fn read_from_packet(packet: &mut Packet) -> Result { + let n: u32 = try!(packet.read_value()); + match n { + STATUS_OFFLINE => Ok(UserStatus::Offline), + STATUS_AWAY => Ok(UserStatus::Away), + STATUS_ONLINE => Ok(UserStatus::Online), + _ => Err(PacketReadError::InvalidUserStatusError(n)), + } + } +} + +impl WriteToPacket for UserStatus { + fn write_to_packet(&self, packet: &mut MutPacket) -> io::Result<()> { + let n = match *self { + UserStatus::Offline => STATUS_OFFLINE, + UserStatus::Away => STATUS_AWAY, + UserStatus::Online => STATUS_ONLINE, + }; + try!(packet.write_value(&n)); + Ok(()) + } +} + +impl ProtoEncode for UserStatus { + fn encode(&self, encoder: &mut ProtoEncoder) -> io::Result<()> { + let value = match *self { + UserStatus::Offline => STATUS_OFFLINE, + UserStatus::Away => STATUS_AWAY, + UserStatus::Online => STATUS_ONLINE, + }; + encoder.encode_u32(value) + } +} + +impl ProtoDecode for UserStatus { + fn decode(decoder: &mut ProtoDecoder) -> Result { + let value = decoder.decode_u32()?; + match value { + STATUS_OFFLINE => Ok(UserStatus::Offline), + STATUS_AWAY => Ok(UserStatus::Away), + STATUS_ONLINE => Ok(UserStatus::Online), + _ => Err(DecodeError::InvalidUserStatusError(value)), + } + } +} + +/// This structure contains the last known information about a fellow user. +#[derive(Clone, Debug, Eq, PartialEq, RustcDecodable, RustcEncodable)] +pub struct User { + /// The last known status of the user. + pub status: UserStatus, + /// The average upload speed of the user. + pub average_speed: usize, + /// ??? Nicotine calls it downloadnum. + pub num_downloads: usize, + /// ??? Unknown field. + pub unknown: usize, + /// The number of files this user shares. + pub num_files: usize, + /// The number of folders this user shares. + pub num_folders: usize, + /// The number of free download slots of this user. + pub num_free_slots: usize, + /// The user's country code. + pub country: String, +} diff --git a/src/room.rs b/src/room.rs index 3c1da50..3af704d 100644 --- a/src/room.rs +++ b/src/room.rs @@ -3,8 +3,7 @@ use std::error; use std::fmt; use std::mem; -use proto::server; -use user; +use proto::{server, User}; /// This enumeration is the list of possible membership states for a chat room. #[derive(Clone, Copy, Debug, RustcDecodable, RustcEncodable)] @@ -237,7 +236,7 @@ impl RoomMap { room_name: &str, owner: Option, mut operators: Vec, - members: &Vec<(String, user::User)>, + members: &Vec<(String, User)>, ) -> Result<(), Error> { // First look up the room struct. let room = try!(self.get_mut_strict(room_name)); diff --git a/src/user.rs b/src/user.rs index 922f51a..7e04a29 100644 --- a/src/user.rs +++ b/src/user.rs @@ -1,94 +1,8 @@ use std::collections; use std::error; use std::fmt; -use std::io; -use proto; - -const STATUS_OFFLINE: u32 = 1; -const STATUS_AWAY: u32 = 2; -const STATUS_ONLINE: u32 = 3; - -/// This enumeration is the list of possible user statuses. -#[derive(Clone, Copy, Debug, Eq, PartialEq, RustcDecodable, RustcEncodable)] -pub enum Status { - /// The user if offline. - Offline, - /// The user is connected, but AFK. - Away, - /// The user is present. - Online, -} - -impl proto::ReadFromPacket for Status { - fn read_from_packet(packet: &mut proto::Packet) -> Result { - let n: u32 = try!(packet.read_value()); - match n { - STATUS_OFFLINE => Ok(Status::Offline), - STATUS_AWAY => Ok(Status::Away), - STATUS_ONLINE => Ok(Status::Online), - _ => Err(proto::PacketReadError::InvalidUserStatusError(n)), - } - } -} - -impl proto::WriteToPacket for Status { - fn write_to_packet(&self, packet: &mut proto::MutPacket) -> io::Result<()> { - let n = match *self { - Status::Offline => STATUS_OFFLINE, - Status::Away => STATUS_AWAY, - Status::Online => STATUS_ONLINE, - }; - try!(packet.write_value(&n)); - Ok(()) - } -} - -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 { - 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. -#[derive(Clone, Debug, Eq, PartialEq, RustcDecodable, RustcEncodable)] -pub struct User { - /// The last known status of the user. - pub status: Status, - /// The average upload speed of the user. - pub average_speed: usize, - /// ??? Nicotine calls it downloadnum. - pub num_downloads: usize, - /// ??? Unknown field. - pub unknown: usize, - /// The number of files this user shares. - pub num_files: usize, - /// The number of folders this user shares. - pub num_folders: usize, - /// The number of free download slots of this user. - pub num_free_slots: usize, - /// The user's country code. - pub country: String, -} +use proto::{User, UserStatus}; /// The error returned when a user name was not found in the user map. #[derive(Debug)] @@ -150,13 +64,10 @@ impl UserMap { } /// Sets the given user's status to the given value, if such a user exists. - pub fn set_status(&mut self, user_name: &str, status: Status) -> Result<(), UserNotFoundError> { - if let Some(user) = self.map.get_mut(user_name) { - user.status = status; - Ok(()) - } else { - Err(UserNotFoundError { user_name: user_name.to_string() }) - } + pub fn set_status(&mut self, user_name: &str, status: UserStatus) -> Result<(), UserNotFoundError> { + let user = self.get_mut_strict(user_name)?; + user.status = status; + Ok(()) } /// Returns the list of (user name, user data) representing all known users.