Browse Source

Move User struct to proto module.

wip
Titouan Rigoudy 7 years ago
parent
commit
7008d6eee9
6 changed files with 121 additions and 124 deletions
  1. +3
    -3
      src/control/response.rs
  2. +4
    -2
      src/proto/mod.rs
  3. +21
    -22
      src/proto/server/response.rs
  4. +86
    -0
      src/proto/user.rs
  5. +2
    -3
      src/room.rs
  6. +5
    -94
      src/user.rs

+ 3
- 3
src/control/response.rs View File

@ -1,5 +1,5 @@
use proto::User;
use room; use room;
use user;
/// This enumeration is the list of possible control responses from the client /// This enumeration is the list of possible control responses from the client
/// to the controller. /// to the controller.
@ -92,11 +92,11 @@ pub struct RoomUserLeftResponse {
#[derive(Debug, RustcDecodable, RustcEncodable)] #[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct UserInfoResponse { pub struct UserInfoResponse {
pub user_name: String, pub user_name: String,
pub user_info: user::User,
pub user_info: User,
} }
/// This stuct contains the last known information about every user. /// This stuct contains the last known information about every user.
#[derive(Debug, RustcDecodable, RustcEncodable)] #[derive(Debug, RustcDecodable, RustcEncodable)]
pub struct UserListResponse { pub struct UserListResponse {
pub user_list: Vec<(String, user::User)>,
pub user_list: Vec<(String, User)>,
} }

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

@ -1,15 +1,17 @@
mod codec;
mod constants; mod constants;
mod handler; mod handler;
mod packet; mod packet;
pub mod peer; pub mod peer;
pub mod server; pub mod server;
mod stream; mod stream;
mod codec;
mod transport; mod transport;
mod user;
pub use self::codec::{DecodeError, ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder};
pub use self::handler::*; pub use self::handler::*;
pub use self::packet::*; pub use self::packet::*;
pub use self::stream::*; pub use self::stream::*;
pub use self::server::{ServerResponse, ServerRequest}; pub use self::server::{ServerResponse, ServerRequest};
pub use self::transport::{PeerTransport, ServerTransport}; pub use self::transport::{PeerTransport, ServerTransport};
pub use self::codec::{DecodeError, ProtoDecode, ProtoDecoder, ProtoEncode, ProtoEncoder};
pub use self::user::{User, UserStatus};

+ 21
- 22
src/proto/server/response.rs View File

@ -2,9 +2,8 @@ use std::io;
use std::net; use std::net;
use proto::server::constants::*; 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 proto::packet::{Packet, PacketReadError, ReadFromPacket};
use user;
/*=================* /*=================*
* SERVER RESPONSE * * SERVER RESPONSE *
@ -522,7 +521,7 @@ impl ProtoDecode for PrivilegedUsersResponse {
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct RoomJoinResponse { pub struct RoomJoinResponse {
pub room_name: String, pub room_name: String,
pub users: Vec<(String, user::User)>,
pub users: Vec<(String, User)>,
pub owner: Option<String>, pub owner: Option<String>,
pub operators: Vec<String>, pub operators: Vec<String>,
} }
@ -538,9 +537,9 @@ impl ReadFromPacket for RoomJoinResponse {
let num_users: usize = try!(packet.read_value()); let num_users: usize = try!(packet.read_value());
for _ in 0..num_users { 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, average_speed: 0,
num_downloads: 0, num_downloads: 0,
unknown: 0, unknown: 0,
@ -631,8 +630,8 @@ struct UserInfo {
num_folders: u32, 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 { Self {
average_speed: user.average_speed as u32, average_speed: user.average_speed as u32,
num_downloads: user.num_downloads 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 { for &(ref user_name, ref user) in &self.users {
user_names.push(user_name); user_names.push(user_name);
user_statuses.push(user.status); 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_free_slots.push(user.num_free_slots as u32);
user_countries.push(&user.country); user_countries.push(&user.country);
} }
@ -703,11 +702,11 @@ impl ProtoEncode for RoomJoinResponse {
fn build_users( fn build_users(
mut names: Vec<String>, mut names: Vec<String>,
mut statuses: Vec<user::Status>,
mut statuses: Vec<UserStatus>,
mut infos: Vec<UserInfo>, mut infos: Vec<UserInfo>,
mut free_slots: Vec<u32>, mut free_slots: Vec<u32>,
mut countries: Vec<String>, mut countries: Vec<String>,
) -> Vec<(String, user::User)> {
) -> Vec<(String, User)> {
let mut users = vec![]; let mut users = vec![];
loop { loop {
@ -721,7 +720,7 @@ fn build_users(
(Some(name), Some(status), Some(info), Some(slots), Some(country)) => { (Some(name), Some(status), Some(info), Some(slots), Some(country)) => {
users.push(( users.push((
name, name,
user::User {
User {
status: status, status: status,
average_speed: info.average_speed as usize, average_speed: info.average_speed as usize,
num_downloads: info.num_downloads as usize, num_downloads: info.num_downloads as usize,
@ -730,7 +729,7 @@ fn build_users(
num_folders: info.num_folders as usize, num_folders: info.num_folders as usize,
num_free_slots: slots as usize, num_free_slots: slots as usize,
country: country, country: country,
},
}
)) ))
} }
_ => break, _ => break,
@ -745,7 +744,7 @@ impl ProtoDecode for RoomJoinResponse {
fn decode(decoder: &mut ProtoDecoder) -> Result<Self, DecodeError> { fn decode(decoder: &mut ProtoDecoder) -> Result<Self, DecodeError> {
let room_name = decoder.decode_string()?; let room_name = decoder.decode_string()?;
let user_names = decoder.decode_vec::<String>()?; let user_names = decoder.decode_vec::<String>()?;
let user_statuses = decoder.decode_vec::<user::Status>()?;
let user_statuses = decoder.decode_vec::<UserStatus>()?;
let user_infos = decoder.decode_vec::<UserInfo>()?; let user_infos = decoder.decode_vec::<UserInfo>()?;
let user_free_slots = decoder.decode_vec::<u32>()?; let user_free_slots = decoder.decode_vec::<u32>()?;
let user_countries = decoder.decode_vec::<String>()?; let user_countries = decoder.decode_vec::<String>()?;
@ -905,13 +904,13 @@ impl ReadFromPacket for RoomTickersResponse {
pub struct RoomUserJoinedResponse { pub struct RoomUserJoinedResponse {
pub room_name: String, pub room_name: String,
pub user_name: String, pub user_name: String,
pub user: user::User,
pub user: User,
} }
impl ReadFromPacket for RoomUserJoinedResponse { impl ReadFromPacket for RoomUserJoinedResponse {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> { fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let room_name = try!(packet.read_value()); 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()); let status = try!(packet.read_value());
@ -927,7 +926,7 @@ impl ReadFromPacket for RoomUserJoinedResponse {
Ok(RoomUserJoinedResponse { Ok(RoomUserJoinedResponse {
room_name: room_name, room_name: room_name,
user_name: user_name, user_name: user_name,
user: user::User {
user: User {
status: status, status: status,
average_speed: average_speed, average_speed: average_speed,
num_downloads: num_downloads, num_downloads: num_downloads,
@ -999,7 +998,7 @@ impl ReadFromPacket for UserInfoResponse {
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub struct UserStatusResponse { pub struct UserStatusResponse {
pub user_name: String, pub user_name: String,
pub status: user::Status,
pub status: UserStatus,
pub is_privileged: bool, pub is_privileged: bool,
} }
@ -1131,8 +1130,8 @@ mod tests {
users: vec![ users: vec![
( (
"alice".to_string(), "alice".to_string(),
user::User {
status: user::Status::Online,
User {
status: UserStatus::Online,
average_speed: 1000, average_speed: 1000,
num_downloads: 1001, num_downloads: 1001,
unknown: 1002, unknown: 1002,
@ -1144,8 +1143,8 @@ mod tests {
), ),
( (
"barbara".to_string(), "barbara".to_string(),
user::User {
status: user::Status::Away,
User {
status: UserStatus::Away,
average_speed: 2000, average_speed: 2000,
num_downloads: 2001, num_downloads: 2001,
unknown: 2002, unknown: 2002,


+ 86
- 0
src/proto/user.rs View File

@ -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<Self, PacketReadError> {
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<Self, DecodeError> {
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,
}

+ 2
- 3
src/room.rs View File

@ -3,8 +3,7 @@ use std::error;
use std::fmt; use std::fmt;
use std::mem; 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. /// This enumeration is the list of possible membership states for a chat room.
#[derive(Clone, Copy, Debug, RustcDecodable, RustcEncodable)] #[derive(Clone, Copy, Debug, RustcDecodable, RustcEncodable)]
@ -237,7 +236,7 @@ impl RoomMap {
room_name: &str, room_name: &str,
owner: Option<String>, owner: Option<String>,
mut operators: Vec<String>, mut operators: Vec<String>,
members: &Vec<(String, user::User)>,
members: &Vec<(String, User)>,
) -> Result<(), Error> { ) -> Result<(), Error> {
// First look up the room struct. // First look up the room struct.
let room = try!(self.get_mut_strict(room_name)); let room = try!(self.get_mut_strict(room_name));


+ 5
- 94
src/user.rs View File

@ -1,94 +1,8 @@
use std::collections; use std::collections;
use std::error; use std::error;
use std::fmt; 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<Self, proto::PacketReadError> {
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<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.
#[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. /// The error returned when a user name was not found in the user map.
#[derive(Debug)] #[derive(Debug)]
@ -150,13 +64,10 @@ impl UserMap {
} }
/// Sets the given user's status to the given value, if such a user exists. /// 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. /// Returns the list of (user name, user data) representing all known users.


Loading…
Cancel
Save