From 12e7e010092af5de240bcbef1e98db92eb88fa86 Mon Sep 17 00:00:00 2001 From: Titouan Rigoudy Date: Sun, 8 May 2016 18:33:21 +0200 Subject: [PATCH] Add UserInfoResponse, both proto and control sides. --- src/client.rs | 25 ++++++++++++++++++++++++ src/control/response.rs | 9 +++++++++ src/proto/server/constants.rs | 1 + src/proto/server/response.rs | 36 +++++++++++++++++++++++++++++++++++ src/user.rs | 17 +++++++++++++++-- 5 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/client.rs b/src/client.rs index 9f975de..ea31011 100644 --- a/src/client.rs +++ b/src/client.rs @@ -286,6 +286,9 @@ impl Client { ServerResponse::RoomUserLeftResponse(response) => self.handle_room_user_left_response(response), + ServerResponse::UserInfoResponse(response) => + self.handle_user_info_response(response), + ServerResponse::UserStatusResponse(response) => self.handle_user_status_response(response), @@ -436,6 +439,28 @@ impl Client { } } + fn handle_user_info_response(&mut self, response: UserInfoResponse) { + let c_response = match self.users.get_mut_strict(&response.user_name) { + Ok(user) => { + user.average_speed = response.average_speed; + user.num_downloads = response.num_downloads; + user.num_files = response.num_files; + user.num_folders = response.num_folders; + control::UserInfoResponse { + user_name: response.user_name, + user_info: user.clone(), + } + }, + Err(err) => { + error!("UserInfoResponse: {}", err); + return + } + }; + self.send_to_controller( + control::Response::UserInfoResponse(c_response) + ); + } + fn handle_user_status_response(&mut self, response: UserStatusResponse) { let result = self.users.set_status( &response.user_name, response.status diff --git a/src/control/response.rs b/src/control/response.rs index 6c5bfa4..5b51966 100644 --- a/src/control/response.rs +++ b/src/control/response.rs @@ -1,4 +1,5 @@ use room; +use user; /// This enumeration is the list of possible control responses from the client /// to the controller. @@ -9,6 +10,7 @@ pub enum Response { RoomLeaveResponse(String), RoomListResponse(RoomListResponse), RoomMessageResponse(RoomMessageResponse), + UserInfoResponse(UserInfoResponse), } #[derive(Debug, RustcEncodable, RustcDecodable)] @@ -63,3 +65,10 @@ pub struct RoomMessageResponse { /// The message itself. pub message: String, } + +/// This struct contains the last known information about a given user. +#[derive(Debug, RustcDecodable, RustcEncodable)] +pub struct UserInfoResponse { + pub user_name: String, + pub user_info: user::User, +} diff --git a/src/proto/server/constants.rs b/src/proto/server/constants.rs index d7ab584..bb39207 100644 --- a/src/proto/server/constants.rs +++ b/src/proto/server/constants.rs @@ -8,6 +8,7 @@ pub const CODE_ROOM_LEAVE: u32 = 15; pub const CODE_ROOM_USER_JOINED: u32 = 16; pub const CODE_ROOM_USER_LEFT: u32 = 17; pub const CODE_CONNECT_TO_PEER: u32 = 18; +pub const CODE_USER_INFO: u32 = 36; pub const CODE_ROOM_LIST: u32 = 64; pub const CODE_PRIVILEGED_USERS: u32 = 69; pub const CODE_PARENT_MIN_SPEED: u32 = 83; diff --git a/src/proto/server/response.rs b/src/proto/server/response.rs index 469b080..5824728 100644 --- a/src/proto/server/response.rs +++ b/src/proto/server/response.rs @@ -22,6 +22,7 @@ pub enum ServerResponse { RoomTickersResponse(RoomTickersResponse), RoomUserJoinedResponse(RoomUserJoinedResponse), RoomUserLeftResponse(RoomUserLeftResponse), + UserInfoResponse(UserInfoResponse), UserStatusResponse(UserStatusResponse), WishlistIntervalResponse(WishlistIntervalResponse), @@ -91,6 +92,11 @@ impl ReadFromPacket for ServerResponse { try!(packet.read_value()) ), + CODE_USER_INFO => + ServerResponse::UserInfoResponse( + try!(packet.read_value()) + ), + CODE_USER_STATUS => ServerResponse::UserStatusResponse( try!(packet.read_value()) @@ -572,6 +578,36 @@ impl ReadFromPacket for RoomUserLeftResponse { } } +/*===========* + * USER INFO * + *===========*/ + +#[derive(Debug)] +pub struct UserInfoResponse { + pub user_name: String, + pub average_speed: usize, + pub num_downloads: usize, + pub num_files: usize, + pub num_folders: usize, +} + +impl ReadFromPacket for UserInfoResponse { + fn read_from_packet(packet: &mut Packet) -> Result { + let user_name = try!(packet.read_value()); + let average_speed = try!(packet.read_value()); + let num_downloads = try!(packet.read_value()); + let num_files = try!(packet.read_value()); + let num_folders = try!(packet.read_value()); + Ok(UserInfoResponse { + user_name: user_name, + average_speed: average_speed, + num_downloads: num_downloads, + num_files: num_files, + num_folders: num_folders, + }) + } +} + /*=============* * USER STATUS * *=============*/ diff --git a/src/user.rs b/src/user.rs index 81436a4..6df4296 100644 --- a/src/user.rs +++ b/src/user.rs @@ -10,7 +10,7 @@ const STATUS_AWAY: u32 = 2; const STATUS_ONLINE: u32 = 3; /// This enumeration is the list of possible user statuses. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, RustcDecodable, RustcEncodable)] pub enum Status { /// The user if offline. Offline, @@ -51,7 +51,7 @@ impl proto::WriteToPacket for Status { /// 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)] +#[derive(Clone, Debug, RustcDecodable, RustcEncodable)] pub struct User { /// The last known status of the user. pub status: Status, @@ -115,6 +115,19 @@ impl UserMap { self.map.get(user_name) } + /// Looks up the given user name in the map, returning a mutable reference + /// to the associated data if found, or an error if not found. + pub fn get_mut_strict(&mut self, user_name: &str) + -> Result<&mut User, UserNotFoundError> + { + match self.map.get_mut(user_name) { + Some(user) => Ok(user), + None => Err(UserNotFoundError { + user_name: user_name.to_string() + }) + } + } + /// Inserts the given user info for the given user name in the mapping. /// If there is already data under that name, it is replaced. pub fn insert(&mut self, user_name: String, user: User) {