Browse Source

Run (deprecated, old, stable-compatible) rustfmt.

wip
Titouan Rigoudy 7 years ago
parent
commit
fbaa25d57e
18 changed files with 759 additions and 841 deletions
  1. +226
    -234
      src/client.rs
  2. +2
    -2
      src/config.rs
  3. +1
    -6
      src/control/mod.rs
  4. +1
    -1
      src/control/response.rs
  5. +37
    -32
      src/control/ws.rs
  6. +4
    -4
      src/main.rs
  7. +64
    -60
      src/proto/codec.rs
  8. +0
    -1
      src/proto/constants.rs
  9. +95
    -84
      src/proto/handler.rs
  10. +38
    -44
      src/proto/packet.rs
  11. +1
    -1
      src/proto/peer/constants.rs
  12. +14
    -22
      src/proto/peer/message.rs
  13. +18
    -18
      src/proto/server/constants.rs
  14. +23
    -19
      src/proto/server/request.rs
  15. +132
    -182
      src/proto/server/response.rs
  16. +27
    -35
      src/proto/stream.rs
  17. +62
    -68
      src/room.rs
  18. +14
    -28
      src/user.rs

+ 226
- 234
src/client.rs View File

@ -35,7 +35,7 @@ enum PeerState {
/// We are waiting for a reverse connection to be established to us.
WaitingFirewalled,
/// The connection is open.
Open
Open,
}
#[derive(Debug)]
@ -60,7 +60,7 @@ pub struct Client {
rooms: room::RoomMap,
users: user::UserMap,
peers: slab::Slab<Peer, usize>,
peers: slab::Slab<Peer, usize>,
}
impl Client {
@ -70,9 +70,8 @@ impl Client {
pub fn new(
proto_tx: mio::deprecated::Sender<proto::Request>,
proto_rx: mpsc::Receiver<proto::Response>,
control_rx: mpsc::Receiver<control::Notification>)
-> Self
{
control_rx: mpsc::Receiver<control::Notification>,
) -> Self {
Client {
proto_tx: proto_tx,
proto_rx: proto_rx,
@ -85,7 +84,7 @@ impl Client {
rooms: room::RoomMap::new(),
users: user::UserMap::new(),
peers: slab::Slab::new(config::MAX_PEERS),
peers: slab::Slab::new(config::MAX_PEERS),
}
}
@ -98,22 +97,20 @@ impl Client {
config::PASSWORD,
config::VER_MAJOR,
config::VER_MINOR,
).unwrap()
).unwrap(),
));
self.send_to_server(server::ServerRequest::SetListenPortRequest(
server::SetListenPortRequest {
port: config::LISTEN_PORT,
}
server::SetListenPortRequest { port: config::LISTEN_PORT },
));
loop {
match self.recv() {
IncomingMessage::Proto(response) =>
self.handle_proto_response(response),
IncomingMessage::Proto(response) => self.handle_proto_response(response),
IncomingMessage::ControlNotification(notif) =>
self.handle_control_notification(notif),
IncomingMessage::ControlNotification(notif) => {
self.handle_control_notification(notif)
}
}
}
}
@ -126,12 +123,15 @@ impl Client {
/// Send a request to the server.
fn send_to_server(&self, request: server::ServerRequest) {
self.proto_tx.send(proto::Request::ServerRequest(request)).unwrap();
self.proto_tx
.send(proto::Request::ServerRequest(request))
.unwrap();
}
/// Send a message to a peer.
fn send_to_peer(&self, peer_id: usize, message: peer::Message) {
self.proto_tx.send(proto::Request::PeerMessage(peer_id, message))
self.proto_tx
.send(proto::Request::PeerMessage(peer_id, message))
.unwrap();
}
@ -141,9 +141,9 @@ impl Client {
None => {
// Silently drop control requests when controller is
// disconnected.
return
},
Some(ref mut control_tx) => control_tx.send(response)
return;
}
Some(ref mut control_tx) => control_tx.send(response),
};
// If we failed to send, we assume it means that the other end of the
// channel has been dropped, i.e. the controller has disconnected.
@ -164,19 +164,18 @@ impl Client {
match notif {
control::Notification::Connected(tx) => {
self.control_tx = Some(tx);
},
}
control::Notification::Disconnected => {
self.control_tx = None;
},
}
control::Notification::Error(e) => {
debug!("Control loop error: {}", e);
self.control_tx = None;
},
}
control::Notification::Request(req) =>
self.handle_control_request(req)
control::Notification::Request(req) => self.handle_control_request(req),
}
}
@ -186,23 +185,23 @@ impl Client {
fn handle_control_request(&mut self, request: control::Request) {
match request {
control::Request::LoginStatusRequest =>
self.handle_login_status_request(),
control::Request::LoginStatusRequest => self.handle_login_status_request(),
control::Request::RoomJoinRequest(room_name) =>
self.handle_room_join_request(room_name),
control::Request::RoomJoinRequest(room_name) => {
self.handle_room_join_request(room_name)
}
control::Request::RoomLeaveRequest(room_name) =>
self.handle_room_leave_request(room_name),
control::Request::RoomLeaveRequest(room_name) => {
self.handle_room_leave_request(room_name)
}
control::Request::RoomListRequest =>
self.handle_room_list_request(),
control::Request::RoomListRequest => self.handle_room_list_request(),
control::Request::RoomMessageRequest(request) =>
self.handle_room_message_request(request),
control::Request::RoomMessageRequest(request) => {
self.handle_room_message_request(request)
}
control::Request::UserListRequest =>
self.handle_user_list_request(),
control::Request::UserListRequest => self.handle_user_list_request(),
/*
_ =>{
@ -216,24 +215,19 @@ impl Client {
let username = config::USERNAME.to_string();
let response = match self.login_status {
LoginStatus::Pending =>
control::LoginStatusResponse::Pending{ username: username },
LoginStatus::Success(ref motd) =>
control::LoginStatusResponse::Success{
username: username,
motd: motd.clone(),
},
LoginStatus::Failure(ref reason) =>
control::LoginStatusResponse::Failure{
username: username,
reason: reason.clone(),
},
LoginStatus::Pending => control::LoginStatusResponse::Pending { username: username },
LoginStatus::Success(ref motd) => control::LoginStatusResponse::Success {
username: username,
motd: motd.clone(),
},
LoginStatus::Failure(ref reason) => control::LoginStatusResponse::Failure {
username: username,
reason: reason.clone(),
},
};
self.send_to_controller(
control::Response::LoginStatusResponse(response)
);
self.send_to_controller(control::Response::LoginStatusResponse(response));
}
fn handle_room_join_request(&mut self, room_name: String) {
@ -245,9 +239,9 @@ impl Client {
room_name: room_name
}
));
},
}
Err(err) => error!("RoomLeaveRequest: {}", err)
Err(err) => error!("RoomLeaveRequest: {}", err),
}
}
@ -260,9 +254,9 @@ impl Client {
room_name: room_name
}
));
},
}
Err(err) => error!("RoomLeaveRequest: {}", err)
Err(err) => error!("RoomLeaveRequest: {}", err),
}
}
@ -270,23 +264,19 @@ impl Client {
// First send the controller client what we have in memory.
let rooms = self.rooms.get_room_list();
self.send_to_controller(control::Response::RoomListResponse(
control::RoomListResponse {
rooms: rooms
}
control::RoomListResponse { rooms: rooms },
));
// Then ask the server for an updated version, which will be forwarded
// to the controller client once received.
self.send_to_server(server::ServerRequest::RoomListRequest);
}
fn handle_room_message_request(
&mut self, request: control::RoomMessageRequest)
{
fn handle_room_message_request(&mut self, request: control::RoomMessageRequest) {
self.send_to_server(server::ServerRequest::RoomMessageRequest(
server::RoomMessageRequest {
room_name: request.room_name,
message: request.message,
}
message: request.message,
},
));
}
@ -294,9 +284,7 @@ impl Client {
// Send the controller client what we have in memory.
let user_list = self.users.get_list();
self.send_to_controller(control::Response::UserListResponse(
control::UserListResponse {
user_list: user_list
}
control::UserListResponse { user_list: user_list },
));
}
@ -306,14 +294,17 @@ impl Client {
fn handle_proto_response(&mut self, response: proto::Response) {
match response {
proto::Response::ServerResponse(server_response) =>
self.handle_server_response(server_response),
proto::Response::ServerResponse(server_response) => {
self.handle_server_response(server_response)
}
proto::Response::PeerConnectionOpen(peer_id) =>
self.handle_peer_connection_open(peer_id),
proto::Response::PeerConnectionOpen(peer_id) => {
self.handle_peer_connection_open(peer_id)
}
proto::Response::PeerConnectionClosed(peer_id) =>
self.handle_peer_connection_closed(peer_id),
proto::Response::PeerConnectionClosed(peer_id) => {
self.handle_peer_connection_closed(peer_id)
}
_ => {
warn!("Unhandled proto response: {:?}", response);
@ -323,19 +314,20 @@ impl Client {
fn handle_peer_connection_closed(&mut self, peer_id: usize) {
let mut occupied_entry = match self.peers.entry(peer_id) {
None | Some(slab::Entry::Vacant(_)) => {
None |
Some(slab::Entry::Vacant(_)) => {
error!("Unknown peer connection {} has closed", peer_id);
return
},
return;
}
Some(slab::Entry::Occupied(occupied_entry)) => occupied_entry
Some(slab::Entry::Occupied(occupied_entry)) => occupied_entry,
};
match occupied_entry.get_mut().state {
PeerState::Open => {
info!("Peer connection {} has closed", peer_id);
occupied_entry.remove();
},
}
PeerState::WaitingFirewalled => {
error!(
@ -343,7 +335,7 @@ impl Client {
peer_id
);
occupied_entry.remove();
},
}
PeerState::Opening => {
info!(
@ -354,16 +346,18 @@ impl Client {
let peer = occupied_entry.get_mut();
peer.state = PeerState::WaitingFirewalled;
self.proto_tx.send(proto::Request::ServerRequest(
server::ServerRequest::ConnectToPeerRequest(
server::ConnectToPeerRequest {
token: peer.token,
user_name: peer.user_name.clone(),
connection_type: peer.connection_type.clone(),
}
)
)).unwrap();
},
self.proto_tx
.send(proto::Request::ServerRequest(
server::ServerRequest::ConnectToPeerRequest(
server::ConnectToPeerRequest {
token: peer.token,
user_name: peer.user_name.clone(),
connection_type: peer.connection_type.clone(),
},
),
))
.unwrap();
}
PeerState::OpeningFirewalled => {
info!(
@ -372,41 +366,36 @@ impl Client {
);
let (peer, _) = occupied_entry.remove();
self.proto_tx.send(proto::Request::ServerRequest(
server::ServerRequest::CannotConnectRequest(
server::CannotConnectRequest {
token: peer.token,
user_name: peer.user_name
}
)
)).unwrap();
self.proto_tx
.send(proto::Request::ServerRequest(
server::ServerRequest::CannotConnectRequest(
server::CannotConnectRequest {
token: peer.token,
user_name: peer.user_name,
},
),
))
.unwrap();
}
}
}
fn handle_peer_connection_open(&mut self, peer_id: usize)
{
fn handle_peer_connection_open(&mut self, peer_id: usize) {
let message = match self.peers.get_mut(peer_id) {
None => {
error!("Unknown peer connection {} is open", peer_id);
return
},
return;
}
Some(peer @ &mut Peer { state: PeerState::Open, .. }) => {
error!(
"Peer connection {} was already open: {:?}",
peer_id, peer
);
return
},
error!("Peer connection {} was already open: {:?}", peer_id, peer);
return;
}
Some(peer @ &mut Peer{state: PeerState::WaitingFirewalled, ..}) => {
error!(
"Peer connection {} was waiting: {:?}",
peer_id, peer
);
return
},
Some(peer @ &mut Peer { state: PeerState::WaitingFirewalled, .. }) => {
error!("Peer connection {} was waiting: {:?}", peer_id, peer);
return;
}
Some(peer @ &mut Peer { state: PeerState::Opening, .. }) => {
info!("Peer connection {} is now open: {:?}", peer_id, peer);
@ -414,19 +403,19 @@ impl Client {
peer.state = PeerState::Open;
// Send a PeerInit.
peer::Message::PeerInit(peer::PeerInit {
user_name: config::USERNAME.to_string(),
user_name: config::USERNAME.to_string(),
connection_type: peer.connection_type.clone(),
token: peer.token,
token: peer.token,
})
},
}
Some(peer @ &mut Peer{state: PeerState::OpeningFirewalled, ..}) => {
Some(peer @ &mut Peer { state: PeerState::OpeningFirewalled, .. }) => {
info!("Peer connection {} is now open: {:?}", peer_id, peer);
// Mark it as open.
peer.state = PeerState::Open;
// Send a PierceFirewall.
peer::Message::PierceFirewall(peer.token)
},
}
};
self.send_to_peer(peer_id, message);
@ -438,71 +427,86 @@ impl Client {
fn handle_server_response(&mut self, response: server::ServerResponse) {
match response {
server::ServerResponse::ConnectToPeerResponse(response) =>
self.handle_connect_to_peer_response(response),
server::ServerResponse::ConnectToPeerResponse(response) => {
self.handle_connect_to_peer_response(response)
}
server::ServerResponse::LoginResponse(response) =>
self.handle_login_response(response),
server::ServerResponse::LoginResponse(response) => self.handle_login_response(response),
server::ServerResponse::PrivilegedUsersResponse(response) =>
self.handle_privileged_users_response(response),
server::ServerResponse::PrivilegedUsersResponse(response) => {
self.handle_privileged_users_response(response)
}
server::ServerResponse::RoomJoinResponse(response) =>
self.handle_room_join_response(response),
server::ServerResponse::RoomJoinResponse(response) => {
self.handle_room_join_response(response)
}
server::ServerResponse::RoomLeaveResponse(response) =>
self.handle_room_leave_response(response),
server::ServerResponse::RoomLeaveResponse(response) => {
self.handle_room_leave_response(response)
}
server::ServerResponse::RoomListResponse(response) =>
self.handle_room_list_response(response),
server::ServerResponse::RoomListResponse(response) => {
self.handle_room_list_response(response)
}
server::ServerResponse::RoomMessageResponse(response) =>
self.handle_room_message_response(response),
server::ServerResponse::RoomMessageResponse(response) => {
self.handle_room_message_response(response)
}
server::ServerResponse::RoomTickersResponse(response) =>
self.handle_room_tickers_response(response),
server::ServerResponse::RoomTickersResponse(response) => {
self.handle_room_tickers_response(response)
}
server::ServerResponse::RoomUserJoinedResponse(response) =>
self.handle_room_user_joined_response(response),
server::ServerResponse::RoomUserJoinedResponse(response) => {
self.handle_room_user_joined_response(response)
}
server::ServerResponse::RoomUserLeftResponse(response) =>
self.handle_room_user_left_response(response),
server::ServerResponse::RoomUserLeftResponse(response) => {
self.handle_room_user_left_response(response)
}
server::ServerResponse::UserInfoResponse(response) =>
self.handle_user_info_response(response),
server::ServerResponse::UserInfoResponse(response) => {
self.handle_user_info_response(response)
}
server::ServerResponse::UserStatusResponse(response) =>
self.handle_user_status_response(response),
server::ServerResponse::UserStatusResponse(response) => {
self.handle_user_status_response(response)
}
server::ServerResponse::UnknownResponse(code) =>
warn!("Unknown response: code {}", code),
server::ServerResponse::UnknownResponse(code) => {
warn!("Unknown response: code {}", code)
}
response => warn!("Unhandled response: {:?}", response),
}
}
fn handle_connect_to_peer_response(
&mut self, response: server::ConnectToPeerResponse)
{
fn handle_connect_to_peer_response(&mut self, response: server::ConnectToPeerResponse) {
let peer = Peer {
user_name: response.user_name,
ip: response.ip,
port: response.port,
user_name: response.user_name,
ip: response.ip,
port: response.port,
connection_type: response.connection_type,
token: response.token,
state: PeerState::OpeningFirewalled
token: response.token,
state: PeerState::OpeningFirewalled,
};
match self.peers.insert(peer) {
Ok(peer_id) => {
info!(
"Opening peer connection {} to {}:{} to pierce firewall",
peer_id, response.ip, response.port
peer_id,
response.ip,
response.port
);
self.proto_tx.send(proto::Request::PeerConnect(
peer_id, response.ip, response.port
)).unwrap();
},
self.proto_tx
.send(proto::Request::PeerConnect(
peer_id,
response.ip,
response.port,
))
.unwrap();
}
Err(peer) => {
warn!(
@ -516,7 +520,11 @@ impl Client {
fn handle_login_response(&mut self, login: server::LoginResponse) {
if let LoginStatus::Pending = self.login_status {
match login {
server::LoginResponse::LoginOk{ motd, ip, password_md5_opt } => {
server::LoginResponse::LoginOk {
motd,
ip,
password_md5_opt,
} => {
info!("Login successful!");
info!("MOTD: \"{}\"", motd);
info!("External IP address: {}", ip);
@ -524,40 +532,44 @@ impl Client {
match password_md5_opt {
Some(_) => {
info!(concat!(
"Connected to official server ",
"as official client"));
},
None => info!(concat!(
"Connected to official server ",
"as unofficial client")),
"as official client"
));
}
None => {
info!(concat!(
"Connected to official server ",
"as unofficial client"
))
}
}
self.login_status = LoginStatus::Success(motd);
},
}
server::LoginResponse::LoginFail{ reason } => {
server::LoginResponse::LoginFail { reason } => {
error!("Login failed: \"{}\"", reason);
self.login_status = LoginStatus::Failure(reason);
}
}
} else {
error!("Received unexpected login response, status = {:?}",
self.login_status);
error!(
"Received unexpected login response, status = {:?}",
self.login_status
);
}
}
fn handle_privileged_users_response(
&mut self, response: server::PrivilegedUsersResponse)
{
fn handle_privileged_users_response(&mut self, response: server::PrivilegedUsersResponse) {
self.users.set_all_privileged(response.users);
}
fn handle_room_join_response(
&mut self, mut response: server::RoomJoinResponse)
{
fn handle_room_join_response(&mut self, mut response: server::RoomJoinResponse) {
// Join the room and store the received information.
let result = self.rooms.join(
&response.room_name, response.owner, response.operators,
&response.users
&response.room_name,
response.owner,
response.operators,
&response.users,
);
if let Err(err) = result {
error!("RoomJoinResponse: {}", err);
@ -569,48 +581,38 @@ impl Client {
self.users.insert(name, user);
}
let control_response = control::RoomJoinResponse {
room_name: response.room_name
};
self.send_to_controller(control::Response::RoomJoinResponse(
control_response
));
let control_response = control::RoomJoinResponse { room_name: response.room_name };
self.send_to_controller(control::Response::RoomJoinResponse(control_response));
}
fn handle_room_leave_response(
&mut self, response: server::RoomLeaveResponse)
{
fn handle_room_leave_response(&mut self, response: server::RoomLeaveResponse) {
if let Err(err) = self.rooms.leave(&response.room_name) {
error!("RoomLeaveResponse: {}", err);
}
self.send_to_controller(control::Response::RoomLeaveResponse(
control::RoomLeaveResponse {
room_name: response.room_name
}
control::RoomLeaveResponse { room_name: response.room_name },
));
}
fn handle_room_list_response(&mut self, response: server::RoomListResponse)
{
fn handle_room_list_response(&mut self, response: server::RoomListResponse) {
// Update the room map in memory.
self.rooms.set_room_list(response);
// Send the updated version to the controller.
let rooms = self.rooms.get_room_list();
self.send_to_controller(control::Response::RoomListResponse(
control::RoomListResponse {
rooms: rooms
}
control::RoomListResponse { rooms: rooms },
));
}
fn handle_room_message_response(
&mut self, response: server::RoomMessageResponse)
{
let result = self.rooms.add_message(&response.room_name, room::Message {
user_name: response.user_name.clone(),
message: response.message.clone(),
});
fn handle_room_message_response(&mut self, response: server::RoomMessageResponse) {
let result = self.rooms.add_message(
&response.room_name,
room::Message {
user_name: response.user_name.clone(),
message: response.message.clone(),
},
);
if let Err(err) = result {
error!("RoomMessageResponse: {}", err);
return;
@ -620,87 +622,77 @@ impl Client {
control::RoomMessageResponse {
room_name: response.room_name,
user_name: response.user_name,
message: response.message,
}
message: response.message,
},
));
}
fn handle_room_tickers_response(
&mut self, response: server::RoomTickersResponse)
{
fn handle_room_tickers_response(&mut self, response: server::RoomTickersResponse) {
let result = self.rooms.set_tickers(
&response.room_name, response.tickers
&response.room_name,
response.tickers,
);
if let Err(e) = result {
error!("RoomTickersResponse: {}", e);
}
}
fn handle_room_user_joined_response(
&mut self, response: server::RoomUserJoinedResponse)
{
fn handle_room_user_joined_response(&mut self, response: server::RoomUserJoinedResponse) {
let result = self.rooms.insert_member(
&response.room_name, response.user_name.clone()
&response.room_name,
response.user_name.clone(),
);
if let Err(err) = result {
error!("RoomUserJoinedResponse: {}", err);
return
return;
}
self.send_to_controller(control::Response::RoomUserJoinedResponse(
control::RoomUserJoinedResponse {
room_name: response.room_name,
user_name: response.user_name,
}
},
));
}
fn handle_room_user_left_response(
&mut self, response: server::RoomUserLeftResponse)
{
fn handle_room_user_left_response(&mut self, response: server::RoomUserLeftResponse) {
let result = self.rooms.remove_member(
&response.room_name, &response.user_name
&response.room_name,
&response.user_name,
);
if let Err(err) = result {
error!("RoomUserLeftResponse: {}", err);
return
return;
}
self.send_to_controller(control::Response::RoomUserLeftResponse(
control::RoomUserLeftResponse {
room_name: response.room_name,
user_name: response.user_name,
}
},
));
}
fn handle_user_info_response(&mut self, response: server::UserInfoResponse)
{
fn handle_user_info_response(&mut self, response: server::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;
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
return;
}
};
self.send_to_controller(
control::Response::UserInfoResponse(c_response)
);
self.send_to_controller(control::Response::UserInfoResponse(c_response));
}
fn handle_user_status_response(
&mut self, response: server::UserStatusResponse)
{
let result = self.users.set_status(
&response.user_name, response.status
);
fn handle_user_status_response(&mut self, response: server::UserStatusResponse) {
let result = self.users.set_status(&response.user_name, response.status);
if let Err(err) = result {
error!("UserStatusResponse: {}", err);
return;


+ 2
- 2
src/config.rs View File

@ -6,8 +6,8 @@ pub const USERNAME: &'static str = "abcdefgh";
// why not even check it in to git
pub const PASSWORD: &'static str = "ijklmnop";
pub const SERVER_HOST : &'static str = "server.slsknet.org";
pub const SERVER_PORT : u16 = 2242;
pub const SERVER_HOST: &'static str = "server.slsknet.org";
pub const SERVER_PORT: u16 = 2242;
pub const LISTEN_HOST: &'static str = "0.0.0.0";
pub const LISTEN_PORT: u16 = 2243;


+ 1
- 6
src/control/mod.rs View File

@ -2,11 +2,6 @@ mod request;
mod response;
mod ws;
pub use self::ws::{
listen,
Notification,
Sender,
SendError,
};
pub use self::ws::{listen, Notification, Sender, SendError};
pub use self::request::*;
pub use self::response::*;

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

@ -51,7 +51,7 @@ pub enum LoginStatusResponse {
username: String,
/// The reason the server gave for refusing the login request.
reason: String,
}
},
}
/// This structure contains the list of all visible rooms, and their associated


+ 37
- 32
src/control/ws.rs View File

@ -37,10 +37,8 @@ pub enum SendError {
impl fmt::Display for SendError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
SendError::JSONEncoderError(ref err) =>
write!(fmt, "JSONEncoderError: {}", err),
SendError::WebSocketError(ref err) =>
write!(fmt, "WebSocketError: {}", err),
SendError::JSONEncoderError(ref err) => write!(fmt, "JSONEncoderError: {}", err),
SendError::WebSocketError(ref err) => write!(fmt, "WebSocketError: {}", err),
}
}
}
@ -49,7 +47,7 @@ impl error::Error for SendError {
fn description(&self) -> &str {
match *self {
SendError::JSONEncoderError(_) => "JSONEncoderError",
SendError::WebSocketError(_) => "WebSocketError",
SendError::WebSocketError(_) => "WebSocketError",
}
}
@ -103,7 +101,7 @@ impl Handler {
fn send_to_client(&self, notification: Notification) -> ws::Result<()> {
match self.client_tx.send(notification) {
Ok(()) => Ok(()),
Err(e)=> {
Err(e) => {
error!("Error sending notification to client: {}", e);
Err(ws::Error::new(ws::ErrorKind::Internal, ""))
}
@ -114,14 +112,16 @@ impl Handler {
impl ws::Handler for Handler {
fn on_open(&mut self, _: ws::Handshake) -> ws::Result<()> {
info!("Websocket open");
self.send_to_client(Notification::Connected(Sender {
sender: self.socket_tx.clone()
}))
self.send_to_client(Notification::Connected(
Sender { sender: self.socket_tx.clone() },
))
}
fn on_close(&mut self, code: ws::CloseCode, reason: &str) {
info!("Websocket closed: code: {:?}, reason: {:?}", code, reason);
self.send_to_client(Notification::Disconnected).unwrap_or(())
self.send_to_client(Notification::Disconnected).unwrap_or(
(),
)
}
fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
@ -131,8 +131,9 @@ impl ws::Handler for Handler {
ws::Message::Binary(_) => {
error!("Received binary websocket message from controller");
return Err(ws::Error::new(
ws::ErrorKind::Protocol, "Binary message not supported"
))
ws::ErrorKind::Protocol,
"Binary message not supported",
));
}
};
@ -141,9 +142,7 @@ impl ws::Handler for Handler {
Ok(control_request) => control_request,
Err(e) => {
error!("Received invalid JSON message from controller: {}", e);
return Err(ws::Error::new(
ws::ErrorKind::Protocol, "Invalid JSON"
))
return Err(ws::Error::new(ws::ErrorKind::Protocol, "Invalid JSON"));
}
};
@ -157,36 +156,42 @@ impl ws::Handler for Handler {
/// Start listening on the socket address stored in configuration, and send
/// control notifications to the client through the given channel.
pub fn listen(client_tx: mpsc::Sender<Notification>) {
let websocket_result = ws::Builder::new().with_settings(ws::Settings {
max_connections: 1,
..ws::Settings::default()
}).build(|socket_tx| Handler {
client_tx: client_tx.clone(),
socket_tx: socket_tx,
});
let websocket_result = ws::Builder::new()
.with_settings(ws::Settings {
max_connections: 1,
..ws::Settings::default()
})
.build(|socket_tx| {
Handler {
client_tx: client_tx.clone(),
socket_tx: socket_tx,
}
});
let websocket = match websocket_result {
Ok(websocket) => websocket,
Err(e) => {
error!("Unable to build websocket: {}", e);
client_tx.send(Notification::Error(
format!("Unable to build websocket: {}", e)
)).unwrap();
return
client_tx
.send(Notification::Error(
format!("Unable to build websocket: {}", e),
))
.unwrap();
return;
}
};
let listen_result = websocket.listen(
(config::CONTROL_HOST, config::CONTROL_PORT)
);
let listen_result = websocket.listen((config::CONTROL_HOST, config::CONTROL_PORT));
match listen_result {
Ok(_) => (),
Err(e) => {
error!("Unable to listen on websocket: {}", e);
client_tx.send(Notification::Error(
format!("Unable to listen on websocket: {}", e)
)).unwrap();
client_tx
.send(Notification::Error(
format!("Unable to listen on websocket: {}", e),
))
.unwrap();
}
}
}

+ 4
- 4
src/main.rs View File

@ -11,7 +11,8 @@ extern crate core;
extern crate crypto;
extern crate encoding;
extern crate futures;
#[macro_use] extern crate log;
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate mio;
extern crate rustc_serialize;
@ -45,9 +46,8 @@ fn main() {
let client_to_proto_tx = proto_agent.channel();
let (control_to_client_tx, control_to_client_rx) = mpsc::channel();
let mut client = client::Client::new(
client_to_proto_tx, proto_to_client_rx, control_to_client_rx
);
let mut client =
client::Client::new(client_to_proto_tx, proto_to_client_rx, control_to_client_rx);
thread::spawn(move || control::listen(control_to_client_tx));
thread::spawn(move || proto_agent.run().unwrap());


+ 64
- 60
src/proto/codec.rs View File

@ -16,7 +16,7 @@ use tokio_io::codec::length_delimited;
use proto::server::ServerResponse;
/// Length of an encoded 32-bit integer in bytes.
const U32_BYTE_LEN : usize = 4;
const U32_BYTE_LEN: usize = 4;
/*==============*
* DECODE ERROR *
@ -44,16 +44,13 @@ pub enum DecodeError {
impl fmt::Display for DecodeError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
DecodeError::InvalidBoolError(n) =>
write!(fmt, "InvalidBoolError: {}", n),
DecodeError::InvalidU16Error(n) =>
write!(fmt, "InvalidU16Error: {}", n),
DecodeError::InvalidStringError(ref bytes) =>
write!(fmt, "InvalidStringError: {:?}", bytes),
DecodeError::InvalidUserStatusError(n) =>
write!(fmt, "InvalidUserStatusError: {}", n),
DecodeError::IOError(ref err) =>
write!(fmt, "IOError: {}", err),
DecodeError::InvalidBoolError(n) => write!(fmt, "InvalidBoolError: {}", n),
DecodeError::InvalidU16Error(n) => write!(fmt, "InvalidU16Error: {}", n),
DecodeError::InvalidStringError(ref bytes) => {
write!(fmt, "InvalidStringError: {:?}", bytes)
}
DecodeError::InvalidUserStatusError(n) => write!(fmt, "InvalidUserStatusError: {}", n),
DecodeError::IOError(ref err) => write!(fmt, "IOError: {}", err),
}
}
}
@ -61,26 +58,21 @@ impl fmt::Display for DecodeError {
impl error::Error for DecodeError {
fn description(&self) -> &str {
match *self {
DecodeError::InvalidBoolError(_) =>
"InvalidBoolError",
DecodeError::InvalidU16Error(_) =>
"InvalidU16Error",
DecodeError::InvalidStringError(_) =>
"InvalidStringError",
DecodeError::InvalidUserStatusError(_) =>
"InvalidUserStatusError",
DecodeError::IOError(_) =>
"IOError",
DecodeError::InvalidBoolError(_) => "InvalidBoolError",
DecodeError::InvalidU16Error(_) => "InvalidU16Error",
DecodeError::InvalidStringError(_) => "InvalidStringError",
DecodeError::InvalidUserStatusError(_) => "InvalidUserStatusError",
DecodeError::IOError(_) => "IOError",
}
}
fn cause(&self) -> Option<&error::Error> {
match *self {
DecodeError::InvalidBoolError(_) => None,
DecodeError::InvalidU16Error(_) => None,
DecodeError::InvalidStringError(_) => None,
DecodeError::InvalidBoolError(_) => None,
DecodeError::InvalidU16Error(_) => None,
DecodeError::InvalidStringError(_) => None,
DecodeError::InvalidUserStatusError(_) => None,
DecodeError::IOError(ref err) => Some(err),
DecodeError::IOError(ref err) => Some(err),
}
}
}
@ -114,7 +106,7 @@ fn unexpected_eof_error(value_type: &str) -> DecodeError {
/// This trait is implemented by types that can be decoded from messages with
/// a `ProtoDecoder`.
/// Only here to enable ProtoDecoder::decode_vec.
pub trait ProtoDecode : Sized {
pub trait ProtoDecode: Sized {
/// Attempts to decode an instance of `Self` using the given decoder.
fn decode(decoder: &mut ProtoDecoder) -> Result<Self, DecodeError>;
}
@ -132,17 +124,17 @@ pub trait ProtoEncode {
pub struct ProtoDecoder<'a> {
// If bytes::Buf was object-safe we would just store &'a Buf. We work
// around this limitation by storing the cursor itself.
inner: &'a mut io::Cursor<BytesMut>
inner: &'a mut io::Cursor<BytesMut>,
}
impl<'a> ProtoDecoder<'a> {
fn new(cursor: &'a mut io::Cursor<BytesMut>) -> ProtoDecoder<'a> {
ProtoDecoder{inner: cursor}
ProtoDecoder { inner: cursor }
}
fn decode_u32(&mut self) -> Result<u32, DecodeError> {
if self.inner.remaining() < U32_BYTE_LEN {
return Err(unexpected_eof_error("u32"))
return Err(unexpected_eof_error("u32"));
}
Ok(self.inner.get_u32::<LittleEndian>())
}
@ -150,19 +142,19 @@ impl<'a> ProtoDecoder<'a> {
fn decode_u16(&mut self) -> Result<u16, DecodeError> {
let n = self.decode_u32()?;
if n > u16::MAX as u32 {
return Err(DecodeError::InvalidU16Error(n))
return Err(DecodeError::InvalidU16Error(n));
}
Ok(n as u16)
}
fn decode_bool(&mut self) -> Result<bool, DecodeError> {
if self.inner.remaining() < 1 {
return Err(unexpected_eof_error("bool"))
return Err(unexpected_eof_error("bool"));
}
match self.inner.get_u8() {
0 => Ok(false),
1 => Ok(true),
n => Err(DecodeError::InvalidBoolError(n))
n => Err(DecodeError::InvalidBoolError(n)),
}
}
@ -174,18 +166,21 @@ impl<'a> ProtoDecoder<'a> {
fn decode_string(&mut self) -> Result<String, DecodeError> {
let len = self.decode_u32()? as usize;
if self.inner.remaining() < len {
return Err(unexpected_eof_error("string"))
return Err(unexpected_eof_error("string"));
}
let result = {
let bytes = &self.inner.bytes()[..len];
WINDOWS_1252.decode(bytes, DecoderTrap::Strict)
.map_err(|_| DecodeError::InvalidStringError(bytes.to_vec()))
WINDOWS_1252.decode(bytes, DecoderTrap::Strict).map_err(
|_| {
DecodeError::InvalidStringError(bytes.to_vec())
},
)
};
self.inner.advance(len);
result
}
fn decode_vec<T : ProtoDecode>(&mut self) -> Result<Vec<T>, DecodeError> {
fn decode_vec<T: ProtoDecode>(&mut self) -> Result<Vec<T>, DecodeError> {
let len = self.decode_u32()? as usize;
let mut vec = Vec::with_capacity(len);
for _ in 0..len {
@ -201,12 +196,12 @@ impl<'a> ProtoDecoder<'a> {
pub struct ProtoEncoder<'a> {
// If bytes::BufMut was object-safe we would store an &'a BufMut. We work
// around this limiation by using BytesMut directly.
inner: &'a mut BytesMut
inner: &'a mut BytesMut,
}
impl<'a> ProtoEncoder<'a> {
fn new(buf: &'a mut BytesMut) -> ProtoEncoder {
ProtoEncoder{inner: buf}
ProtoEncoder { inner: buf }
}
fn encode_u32(&mut self, val: u32) -> io::Result<()> {
@ -231,7 +226,7 @@ impl<'a> ProtoEncoder<'a> {
fn encode_ipv4_addr(&mut self, addr: net::Ipv4Addr) -> io::Result<()> {
let mut octets = addr.octets();
octets.reverse(); // Little endian.
octets.reverse(); // Little endian.
self.inner.extend(&octets);
Ok(())
}
@ -250,7 +245,7 @@ impl<'a> ProtoEncoder<'a> {
Ok(())
}
fn encode_vec<T : ProtoEncode>(&mut self, vec: &[T]) -> io::Result<()> {
fn encode_vec<T: ProtoEncode>(&mut self, vec: &[T]) -> io::Result<()> {
self.encode_u32(vec.len() as u32)?;
for ref item in vec {
item.encode(self)?;
@ -343,7 +338,10 @@ impl<T: ProtoEncode> ProtoEncode for Vec<T> {
*=================*/
fn new_length_prefixed_framed<T, B>(inner: T) -> length_delimited::Framed<T, B>
where T: AsyncRead + AsyncWrite, B: IntoBuf {
where
T: AsyncRead + AsyncWrite,
B: IntoBuf,
{
length_delimited::Builder::new()
.length_field_length(4)
.little_endian()
@ -356,8 +354,7 @@ impl Decoder for ServerResponseDecoder {
type Item = ServerResponse;
type Error = DecodeError;
fn decode(&mut self, buf: &mut BytesMut)
-> Result<Option<Self::Item>, Self::Error> {
fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
unimplemented!();
}
}
@ -383,14 +380,14 @@ mod tests {
}
// A few integers and their corresponding byte encodings.
const U32_ENCODINGS : [(u32, [u8; 4]); 8] = [
(0, [ 0, 0, 0, 0]),
(255, [255, 0, 0, 0]),
(256, [ 0, 1, 0, 0]),
(65535, [255, 255, 0, 0]),
(65536, [ 0, 0, 1, 0]),
(16777215, [255, 255, 255, 0]),
(16777216, [ 0, 0, 0, 1]),
const U32_ENCODINGS: [(u32, [u8; 4]); 8] = [
(0, [0, 0, 0, 0]),
(255, [255, 0, 0, 0]),
(256, [0, 1, 0, 0]),
(65535, [255, 255, 0, 0]),
(65536, [0, 0, 1, 0]),
(16777215, [255, 255, 255, 0]),
(16777216, [0, 0, 0, 1]),
(u32::MAX, [255, 255, 255, 255]),
];
@ -458,7 +455,9 @@ mod tests {
let mut expected_bytes = vec![13];
expected_bytes.extend(encoded_bytes);
ProtoEncoder::new(&mut bytes).encode_u16(val as u16).unwrap();
ProtoEncoder::new(&mut bytes)
.encode_u16(val as u16)
.unwrap();
assert_eq!(bytes, expected_bytes);
}
}
@ -485,7 +484,9 @@ mod tests {
expected_bytes.extend(encoded_bytes);
let addr = net::Ipv4Addr::from(val);
ProtoEncoder::new(&mut bytes).encode_ipv4_addr(addr).unwrap();
ProtoEncoder::new(&mut bytes)
.encode_ipv4_addr(addr)
.unwrap();
assert_eq!(bytes, expected_bytes);
}
}
@ -501,12 +502,13 @@ mod tests {
}
// A few strings and their corresponding encodings.
const STRING_ENCODINGS: [(&'static str, &'static [u8]); 3] = [
("", &[0, 0, 0, 0]),
("hey!", &[4, 0, 0, 0, 104, 101, 121, 33]),
// Windows 1252 specific codepoints.
("‘’“”€", &[5, 0, 0, 0, 145, 146, 147, 148, 128]),
];
const STRING_ENCODINGS: [(&'static str, &'static [u8]); 3] =
[
("", &[0, 0, 0, 0]),
("hey!", &[4, 0, 0, 0, 104, 101, 121, 33]),
// Windows 1252 specific codepoints.
("‘’“”€", &[5, 0, 0, 0, 145, 146, 147, 148, 128]),
];
#[test]
fn encode_string() {
@ -524,7 +526,9 @@ mod tests {
#[should_panic]
fn encode_invalid_string() {
let mut bytes = BytesMut::with_capacity(100);
ProtoEncoder::new(&mut bytes).encode_string("忠犬ハチ公").unwrap();
ProtoEncoder::new(&mut bytes)
.encode_string("忠犬ハチ公")
.unwrap();
}
#[test]


+ 0
- 1
src/proto/constants.rs View File

@ -3,4 +3,3 @@ pub const U32_SIZE: usize = 4;
pub const MAX_MESSAGE_SIZE: usize = MAX_PACKET_SIZE - U32_SIZE;
pub const MAX_PORT: u32 = (1 << 16) - 1;

+ 95
- 84
src/proto/handler.rs View File

@ -32,7 +32,7 @@ const LISTEN_TOKEN: usize = config::MAX_PEERS + 1;
pub enum Request {
PeerConnect(usize, net::Ipv4Addr, u16),
PeerMessage(usize, peer::Message),
ServerRequest(ServerRequest)
ServerRequest(ServerRequest),
}
#[derive(Debug)]
@ -67,7 +67,7 @@ impl SendPacket for ServerResponseSender {
*======================*/
pub struct PeerResponseSender {
sender: mpsc::Sender<Response>,
sender: mpsc::Sender<Response>,
peer_id: usize,
}
@ -101,54 +101,53 @@ struct Handler {
}
fn listener_bind<U>(addr_spec: U) -> io::Result<mio::tcp::TcpListener>
where U: ToSocketAddrs + fmt::Debug
where
U: ToSocketAddrs + fmt::Debug,
{
for socket_addr in try!(addr_spec.to_socket_addrs()) {
if let Ok(listener) = mio::tcp::TcpListener::bind(&socket_addr) {
return Ok(listener)
return Ok(listener);
}
}
Err(io::Error::new(
io::ErrorKind::Other,
format!("Cannot bind to {:?}", addr_spec)
format!("Cannot bind to {:?}", addr_spec),
))
}
impl Handler {
fn new(
client_tx: mpsc::Sender<Response>,
event_loop: &mut mio::deprecated::EventLoop<Self>)
-> io::Result<Self>
{
event_loop: &mut mio::deprecated::EventLoop<Self>,
) -> io::Result<Self> {
let host = config::SERVER_HOST;
let port = config::SERVER_PORT;
let server_stream = try!(Stream::new(
(host, port),
ServerResponseSender(client_tx.clone())
ServerResponseSender(client_tx.clone()),
));
info!("Connected to server at {}:{}", host, port);
let listener = try!(
listener_bind((config::LISTEN_HOST, config::LISTEN_PORT))
);
let listener = try!(listener_bind((config::LISTEN_HOST, config::LISTEN_PORT)));
info!(
"Listening for connections on {}:{}",
config::LISTEN_HOST, config::LISTEN_PORT
config::LISTEN_HOST,
config::LISTEN_PORT
);
try!(event_loop.register(
server_stream.evented(),
mio::Token(SERVER_TOKEN),
mio::Ready::all(),
mio::PollOpt::edge() | mio::PollOpt::oneshot()
mio::PollOpt::edge() | mio::PollOpt::oneshot(),
));
try!(event_loop.register(
&listener,
mio::Token(LISTEN_TOKEN),
mio::Ready::all(),
mio::PollOpt::edge() | mio::PollOpt::oneshot()
mio::PollOpt::edge() | mio::PollOpt::oneshot(),
));
Ok(Handler {
@ -167,14 +166,14 @@ impl Handler {
peer_id: usize,
ip: net::Ipv4Addr,
port: u16,
event_loop: &mut mio::deprecated::EventLoop<Self>)
-> Result<(), String>
{
event_loop: &mut mio::deprecated::EventLoop<Self>,
) -> Result<(), String> {
let vacant_entry = match self.peer_streams.entry(peer_id) {
None => return Err("id out of range".to_string()),
Some(slab::Entry::Occupied(occupied_entry)) =>
return Err("id already taken".to_string()),
Some(slab::Entry::Occupied(occupied_entry)) => {
return Err("id already taken".to_string())
}
Some(slab::Entry::Vacant(vacant_entry)) => vacant_entry,
};
@ -182,22 +181,24 @@ impl Handler {
info!("Opening peer connection {} to {}:{}", peer_id, ip, port);
let sender = PeerResponseSender {
sender: self.client_tx.clone(),
peer_id: peer_id
sender: self.client_tx.clone(),
peer_id: peer_id,
};
let peer_stream = match Stream::new((ip, port), sender) {
Ok(peer_stream) => peer_stream,
Err(err) => return Err(format!("i/o error: {}", err))
Err(err) => return Err(format!("i/o error: {}", err)),
};
event_loop.register(
peer_stream.evented(),
mio::Token(peer_id),
mio::Ready::all(),
mio::PollOpt::edge() | mio::PollOpt::oneshot()
).unwrap();
event_loop
.register(
peer_stream.evented(),
mio::Token(peer_id),
mio::Ready::all(),
mio::PollOpt::edge() | mio::PollOpt::oneshot(),
)
.unwrap();
vacant_entry.insert(peer_stream);
@ -205,20 +206,24 @@ impl Handler {
}
fn process_server_intent(
&mut self, intent: Intent, event_loop: &mut mio::deprecated::EventLoop<Self>)
{
&mut self,
intent: Intent,
event_loop: &mut mio::deprecated::EventLoop<Self>,
) {
match intent {
Intent::Done => {
error!("Server connection closed");
// TODO notify client and shut down
},
}
Intent::Continue(event_set) => {
event_loop.reregister(
self.server_stream.evented(),
mio::Token(SERVER_TOKEN),
event_set,
mio::PollOpt::edge() | mio::PollOpt::oneshot()
).unwrap();
event_loop
.reregister(
self.server_stream.evented(),
mio::Token(SERVER_TOKEN),
event_set,
mio::PollOpt::edge() | mio::PollOpt::oneshot(),
)
.unwrap();
}
}
}
@ -227,26 +232,28 @@ impl Handler {
&mut self,
intent: Intent,
token: mio::Token,
event_loop: &mut mio::deprecated::EventLoop<Self>)
{
event_loop: &mut mio::deprecated::EventLoop<Self>,
) {
match intent {
Intent::Done => {
self.peer_streams.remove(token.0);
self.client_tx.send(
Response::PeerConnectionClosed(token.0)
).unwrap();
},
self.client_tx
.send(Response::PeerConnectionClosed(token.0))
.unwrap();
}
Intent::Continue(event_set) => {
if let Some(peer_stream) = self.peer_streams.get_mut(token.0) {
event_loop.reregister(
peer_stream.evented(),
token,
event_set,
mio::PollOpt::edge() | mio::PollOpt::oneshot()
).unwrap();
event_loop
.reregister(
peer_stream.evented(),
token,
event_set,
mio::PollOpt::edge() | mio::PollOpt::oneshot(),
)
.unwrap();
}
},
}
}
}
}
@ -255,9 +262,12 @@ impl mio::deprecated::Handler for Handler {
type Timeout = ();
type Message = Request;
fn ready(&mut self, event_loop: &mut mio::deprecated::EventLoop<Self>,
token: mio::Token, event_set: mio::Ready)
{
fn ready(
&mut self,
event_loop: &mut mio::deprecated::EventLoop<Self>,
token: mio::Token,
event_set: mio::Ready,
) {
match token {
mio::Token(LISTEN_TOKEN) => {
if event_set.is_readable() {
@ -266,25 +276,27 @@ impl mio::deprecated::Handler for Handler {
Ok((sock, addr)) => {
// TODO add it to peer streams
info!("Peer connection accepted from {}", addr);
},
}
Err(err) => {
error!("Cannot accept peer connection: {}", err);
}
}
}
event_loop.reregister(
&self.listener,
token,
mio::Ready::all(),
mio::PollOpt::edge() | mio::PollOpt::oneshot()
).unwrap();
},
event_loop
.reregister(
&self.listener,
token,
mio::Ready::all(),
mio::PollOpt::edge() | mio::PollOpt::oneshot(),
)
.unwrap();
}
mio::Token(SERVER_TOKEN) => {
let intent = self.server_stream.on_ready(event_set);
self.process_server_intent(intent, event_loop);
},
}
mio::Token(peer_id) => {
let intent = match self.peer_streams.get_mut(peer_id) {
@ -297,22 +309,22 @@ impl mio::deprecated::Handler for Handler {
}
}
fn notify(&mut self, event_loop: &mut mio::deprecated::EventLoop<Self>,
request: Request)
{
fn notify(&mut self, event_loop: &mut mio::deprecated::EventLoop<Self>, request: Request) {
match request {
Request::PeerConnect(peer_id, ip, port) =>
if let Err(err) =
self.connect_to_peer(peer_id, ip, port, event_loop)
{
Request::PeerConnect(peer_id, ip, port) => {
if let Err(err) = self.connect_to_peer(peer_id, ip, port, event_loop) {
error!(
"Cannot open peer connection {} to {}:{}: {}",
peer_id, ip, port, err
peer_id,
ip,
port,
err
);
self.client_tx.send(
Response::PeerConnectionClosed(peer_id)
).unwrap();
},
self.client_tx
.send(Response::PeerConnectionClosed(peer_id))
.unwrap();
}
}
Request::PeerMessage(peer_id, message) => {
let intent = match self.peer_streams.get_mut(peer_id) {
@ -320,20 +332,19 @@ impl mio::deprecated::Handler for Handler {
None => {
error!(
"Cannot send peer message {:?}: unknown id {}",
message, peer_id
message,
peer_id
);
return
return;
}
};
self.process_peer_intent(
intent, mio::Token(peer_id), event_loop
);
},
self.process_peer_intent(intent, mio::Token(peer_id), event_loop);
}
Request::ServerRequest(server_request) => {
let intent = self.server_stream.on_notify(&server_request);
self.process_server_intent(intent, event_loop);
},
}
}
}
}
@ -342,7 +353,7 @@ pub type Sender = mio::deprecated::Sender<Request>;
pub struct Agent {
event_loop: mio::deprecated::EventLoop<Handler>,
handler: Handler,
handler: Handler,
}
impl Agent {
@ -355,7 +366,7 @@ impl Agent {
Ok(Agent {
event_loop: event_loop,
handler: handler,
handler: handler,
})
}


+ 38
- 44
src/proto/packet.rs View File

@ -42,13 +42,14 @@ impl Packet {
fn from_wire(bytes: Vec<u8>) -> Self {
Packet {
cursor: U32_SIZE,
bytes: bytes,
bytes: bytes,
}
}
/// Provides the main way to read data out of a binary packet.
pub fn read_value<T>(&mut self) -> Result<T, PacketReadError>
where T: ReadFromPacket
where
T: ReadFromPacket,
{
T::read_from_packet(self)
}
@ -72,14 +73,13 @@ impl MutPacket {
/// Returns an empty packet with the given packet code.
pub fn new() -> Self {
// Leave space for the eventual size of the packet.
MutPacket {
bytes: vec![0; U32_SIZE]
}
MutPacket { bytes: vec![0; U32_SIZE] }
}
/// Provides the main way to write data into a binary packet.
pub fn write_value<T>(&mut self, val: &T) -> io::Result<()>
where T: WriteToPacket
where
T: WriteToPacket,
{
val.write_to_packet(self)
}
@ -129,16 +129,15 @@ pub enum PacketReadError {
impl fmt::Display for PacketReadError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
PacketReadError::InvalidBoolError(n) =>
write!(fmt, "InvalidBoolError: {}", n),
PacketReadError::InvalidU16Error(n) =>
write!(fmt, "InvalidU16Error: {}", n),
PacketReadError::InvalidStringError(ref bytes) =>
write!(fmt, "InvalidStringError: {:?}", bytes),
PacketReadError::InvalidUserStatusError(n) =>
write!(fmt, "InvalidUserStatusError: {}", n),
PacketReadError::IOError(ref err) =>
write!(fmt, "IOError: {}", err),
PacketReadError::InvalidBoolError(n) => write!(fmt, "InvalidBoolError: {}", n),
PacketReadError::InvalidU16Error(n) => write!(fmt, "InvalidU16Error: {}", n),
PacketReadError::InvalidStringError(ref bytes) => {
write!(fmt, "InvalidStringError: {:?}", bytes)
}
PacketReadError::InvalidUserStatusError(n) => {
write!(fmt, "InvalidUserStatusError: {}", n)
}
PacketReadError::IOError(ref err) => write!(fmt, "IOError: {}", err),
}
}
}
@ -146,26 +145,21 @@ impl fmt::Display for PacketReadError {
impl error::Error for PacketReadError {
fn description(&self) -> &str {
match *self {
PacketReadError::InvalidBoolError(_) =>
"InvalidBoolError",
PacketReadError::InvalidU16Error(_) =>
"InvalidU16Error",
PacketReadError::InvalidStringError(_) =>
"InvalidStringError",
PacketReadError::InvalidUserStatusError(_) =>
"InvalidUserStatusError",
PacketReadError::IOError(_) =>
"IOError",
PacketReadError::InvalidBoolError(_) => "InvalidBoolError",
PacketReadError::InvalidU16Error(_) => "InvalidU16Error",
PacketReadError::InvalidStringError(_) => "InvalidStringError",
PacketReadError::InvalidUserStatusError(_) => "InvalidUserStatusError",
PacketReadError::IOError(_) => "IOError",
}
}
fn cause(&self) -> Option<&error::Error> {
match *self {
PacketReadError::InvalidBoolError(_) => None,
PacketReadError::InvalidU16Error(_) => None,
PacketReadError::InvalidStringError(_) => None,
PacketReadError::InvalidBoolError(_) => None,
PacketReadError::InvalidU16Error(_) => None,
PacketReadError::InvalidStringError(_) => None,
PacketReadError::InvalidUserStatusError(_) => None,
PacketReadError::IOError(ref err) => Some(err),
PacketReadError::IOError(ref err) => Some(err),
}
}
}
@ -206,7 +200,7 @@ impl ReadFromPacket for bool {
match try!(packet.read_u8()) {
0 => Ok(false),
1 => Ok(true),
n => Err(PacketReadError::InvalidBoolError(n))
n => Err(PacketReadError::InvalidBoolError(n)),
}
}
}
@ -216,7 +210,7 @@ impl ReadFromPacket for u16 {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let n = try!(u32::read_from_packet(packet));
if n > MAX_PORT {
return Err(PacketReadError::InvalidU16Error(n))
return Err(PacketReadError::InvalidU16Error(n));
}
Ok(n as u16)
}
@ -241,7 +235,7 @@ impl ReadFromPacket for String {
match ISO_8859_1.decode(&buffer, DecoderTrap::Strict) {
Ok(string) => Ok(string),
Err(_) => Err(PacketReadError::InvalidStringError(buffer))
Err(_) => Err(PacketReadError::InvalidStringError(buffer)),
}
}
}
@ -301,7 +295,7 @@ impl WriteToPacket for str {
Ok(bytes) => bytes,
Err(_) => {
let copy = self.to_string();
return Err(io::Error::new(io::ErrorKind::Other, copy))
return Err(io::Error::new(io::ErrorKind::Other, copy));
}
};
// Then write the bytes to the packet.
@ -335,17 +329,17 @@ enum State {
#[derive(Debug)]
pub struct Parser {
state: State,
state: State,
num_bytes_left: usize,
buffer: Vec<u8>,
buffer: Vec<u8>,
}
impl Parser {
pub fn new() -> Self {
Parser {
state: State::ReadingLength,
state: State::ReadingLength,
num_bytes_left: U32_SIZE,
buffer: vec![0; U32_SIZE],
buffer: vec![0; U32_SIZE],
}
}
@ -359,7 +353,8 @@ impl Parser {
/// responsible for calling it once more to ensure that all packets are
/// read as soon as possible.
pub fn try_read<U>(&mut self, stream: &mut U) -> io::Result<Option<Packet>>
where U: io::Read
where
U: io::Read,
{
// Try to read as many bytes as we currently need from the underlying
// byte stream.
@ -369,7 +364,7 @@ impl Parser {
Some(num_bytes_read) => {
self.num_bytes_left -= num_bytes_read;
},
}
}
// If we haven't read enough bytes, return.
@ -383,8 +378,7 @@ impl Parser {
// If we have finished reading the length prefix, then
// deserialize it, switch states and try to read the packet
// bytes.
let message_len =
LittleEndian::read_u32(&mut self.buffer) as usize;
let message_len = LittleEndian::read_u32(&mut self.buffer) as usize;
if message_len > MAX_MESSAGE_SIZE {
unimplemented!();
};
@ -392,14 +386,14 @@ impl Parser {
self.num_bytes_left = message_len;
self.buffer.resize(message_len + U32_SIZE, 0);
self.try_read(stream)
},
}
State::ReadingPacket => {
// If we have finished reading the packet, swap the full buffer
// out and return the packet made from the full buffer.
self.state = State::ReadingLength;
self.num_bytes_left = U32_SIZE;
let new_buffer = vec![0;U32_SIZE];
let new_buffer = vec![0; U32_SIZE];
let old_buffer = mem::replace(&mut self.buffer, new_buffer);
Ok(Some(Packet::from_wire(old_buffer)))
}


+ 1
- 1
src/proto/peer/constants.rs View File

@ -1,2 +1,2 @@
pub const CODE_PIERCE_FIREWALL: u32 = 0;
pub const CODE_PEER_INIT: u32 = 1;
pub const CODE_PEER_INIT: u32 = 1;

+ 14
- 22
src/proto/peer/message.rs View File

@ -1,8 +1,6 @@
use std::io;
use super::super::{
MutPacket, Packet, PacketReadError, ReadFromPacket, WriteToPacket
};
use super::super::{MutPacket, Packet, PacketReadError, ReadFromPacket, WriteToPacket};
use super::constants::*;
/*=========*
@ -21,24 +19,19 @@ impl ReadFromPacket for Message {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let code: u32 = try!(packet.read_value());
let message = match code {
CODE_PIERCE_FIREWALL =>
Message::PierceFirewall(
try!(packet.read_value())
),
CODE_PIERCE_FIREWALL => Message::PierceFirewall(try!(packet.read_value())),
CODE_PEER_INIT =>
Message::PeerInit(
try!(packet.read_value())
),
CODE_PEER_INIT => Message::PeerInit(try!(packet.read_value())),
code => Message::Unknown(code)
code => Message::Unknown(code),
};
let bytes_remaining = packet.bytes_remaining();
if bytes_remaining > 0 {
warn!(
"Peer message with code {} contains {} extra bytes",
code, bytes_remaining
code,
bytes_remaining
)
}
@ -52,12 +45,12 @@ impl WriteToPacket for Message {
Message::PierceFirewall(ref token) => {
try!(packet.write_value(&CODE_PIERCE_FIREWALL));
try!(packet.write_value(token));
},
}
Message::PeerInit(ref request) => {
try!(packet.write_value(&CODE_PEER_INIT));
try!(packet.write_value(request));
},
}
Message::Unknown(_) => unreachable!(),
}
@ -67,20 +60,20 @@ impl WriteToPacket for Message {
#[derive(Clone, Debug)]
pub struct PeerInit {
pub user_name: String,
pub user_name: String,
pub connection_type: String,
pub token: u32,
pub token: u32,
}
impl ReadFromPacket for PeerInit {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let user_name = try!(packet.read_value());
let user_name = try!(packet.read_value());
let connection_type = try!(packet.read_value());
let token = try!(packet.read_value());
let token = try!(packet.read_value());
Ok(PeerInit {
user_name: user_name,
user_name: user_name,
connection_type: connection_type,
token: token,
token: token,
})
}
}
@ -93,4 +86,3 @@ impl WriteToPacket for PeerInit {
Ok(())
}
}

+ 18
- 18
src/proto/server/constants.rs View File

@ -1,19 +1,19 @@
pub const CODE_LOGIN: u32 = 1;
pub const CODE_SET_LISTEN_PORT: u32 = 2;
pub const CODE_PEER_ADDRESS: u32 = 3;
pub const CODE_USER_STATUS: u32 = 7;
pub const CODE_ROOM_MESSAGE: u32 = 13;
pub const CODE_ROOM_JOIN: u32 = 14;
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_FILE_SEARCH: u32 = 26;
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;
pub const CODE_LOGIN: u32 = 1;
pub const CODE_SET_LISTEN_PORT: u32 = 2;
pub const CODE_PEER_ADDRESS: u32 = 3;
pub const CODE_USER_STATUS: u32 = 7;
pub const CODE_ROOM_MESSAGE: u32 = 13;
pub const CODE_ROOM_JOIN: u32 = 14;
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_FILE_SEARCH: u32 = 26;
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;
pub const CODE_PARENT_SPEED_RATIO: u32 = 84;
pub const CODE_WISHLIST_INTERVAL: u32 = 104;
pub const CODE_ROOM_TICKERS: u32 = 113;
pub const CODE_CANNOT_CONNECT: u32 = 1001;
pub const CODE_WISHLIST_INTERVAL: u32 = 104;
pub const CODE_ROOM_TICKERS: u32 = 113;
pub const CODE_CANNOT_CONNECT: u32 = 1001;

+ 23
- 19
src/proto/server/request.rs View File

@ -31,51 +31,51 @@ impl WriteToPacket for ServerRequest {
ServerRequest::CannotConnectRequest(ref request) => {
try!(packet.write_value(&CODE_CANNOT_CONNECT));
try!(packet.write_value(request));
},
}
ServerRequest::ConnectToPeerRequest(ref request) => {
try!(packet.write_value(&CODE_CONNECT_TO_PEER));
try!(packet.write_value(request));
},
}
ServerRequest::FileSearchRequest(ref request) => {
try!(packet.write_value(&CODE_FILE_SEARCH));
try!(packet.write_value(request));
},
}
ServerRequest::LoginRequest(ref request) => {
try!(packet.write_value(&CODE_LOGIN));
try!(packet.write_value(request));
},
}
ServerRequest::PeerAddressRequest(ref request) => {
try!(packet.write_value(&CODE_PEER_ADDRESS));
try!(packet.write_value(request));
},
}
ServerRequest::RoomJoinRequest(ref request) => {
try!(packet.write_value(&CODE_ROOM_JOIN));
try!(packet.write_value(request));
},
}
ServerRequest::RoomLeaveRequest(ref request) => {
try!(packet.write_value(&CODE_ROOM_LEAVE));
try!(packet.write_value(request));
},
}
ServerRequest::RoomListRequest => {
try!(packet.write_value(&CODE_ROOM_LIST));
},
}
ServerRequest::RoomMessageRequest(ref request) => {
try!(packet.write_value(&CODE_ROOM_MESSAGE));
try!(packet.write_value(request));
},
}
ServerRequest::SetListenPortRequest(ref request) => {
try!(packet.write_value(&CODE_SET_LISTEN_PORT));
try!(packet.write_value(request));
},
}
ServerRequest::UserStatusRequest(ref request) => {
try!(packet.write_value(&CODE_USER_STATUS));
@ -98,7 +98,7 @@ fn md5_str(string: &str) -> String {
#[derive(Debug)]
pub struct CannotConnectRequest {
pub token: u32,
pub token: u32,
pub user_name: String,
}
@ -116,8 +116,8 @@ impl WriteToPacket for CannotConnectRequest {
#[derive(Debug)]
pub struct ConnectToPeerRequest {
pub token: u32,
pub user_name: String,
pub token: u32,
pub user_name: String,
pub connection_type: String,
}
@ -137,7 +137,7 @@ impl WriteToPacket for ConnectToPeerRequest {
#[derive(Debug)]
pub struct FileSearchRequest {
pub ticket: u32,
pub query: String,
pub query: String,
}
impl WriteToPacket for FileSearchRequest {
@ -161,8 +161,12 @@ pub struct LoginRequest {
}
impl LoginRequest {
pub fn new(username: &str, password: &str, major: u32, minor: u32)
-> Result<Self, &'static str> {
pub fn new(
username: &str,
password: &str,
major: u32,
minor: u32,
) -> Result<Self, &'static str> {
if password.len() > 0 {
Ok(LoginRequest {
username: username.to_string(),
@ -213,7 +217,7 @@ impl WriteToPacket for PeerAddressRequest {
#[derive(Debug)]
pub struct RoomJoinRequest {
pub room_name: String
pub room_name: String,
}
impl WriteToPacket for RoomJoinRequest {
@ -229,7 +233,7 @@ impl WriteToPacket for RoomJoinRequest {
#[derive(Debug)]
pub struct RoomLeaveRequest {
pub room_name: String
pub room_name: String,
}
impl WriteToPacket for RoomLeaveRequest {
@ -246,7 +250,7 @@ impl WriteToPacket for RoomLeaveRequest {
#[derive(Debug)]
pub struct RoomMessageRequest {
pub room_name: String,
pub message: String,
pub message: String,
}
impl WriteToPacket for RoomMessageRequest {


+ 132
- 182
src/proto/server/response.rs View File

@ -38,97 +38,61 @@ impl ReadFromPacket for ServerResponse {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let code: u32 = try!(packet.read_value());
let resp = match code {
CODE_CONNECT_TO_PEER =>
ServerResponse::ConnectToPeerResponse(
try!(packet.read_value())
),
CODE_FILE_SEARCH =>
ServerResponse::FileSearchResponse(
try!(packet.read_value())
),
CODE_LOGIN =>
ServerResponse::LoginResponse(
try!(packet.read_value())
),
CODE_PEER_ADDRESS =>
ServerResponse::PeerAddressResponse(
try!(packet.read_value())
),
CODE_PRIVILEGED_USERS =>
ServerResponse::PrivilegedUsersResponse(
try!(packet.read_value())
),
CODE_ROOM_JOIN =>
ServerResponse::RoomJoinResponse(
try!(packet.read_value())
),
CODE_ROOM_LEAVE =>
ServerResponse::RoomLeaveResponse(
try!(packet.read_value())
),
CODE_ROOM_LIST =>
ServerResponse::RoomListResponse(
try!(packet.read_value())
),
CODE_ROOM_MESSAGE =>
ServerResponse::RoomMessageResponse(
try!(packet.read_value())
),
CODE_ROOM_TICKERS =>
ServerResponse::RoomTickersResponse(
try!(packet.read_value())
),
CODE_ROOM_USER_JOINED =>
ServerResponse::RoomUserJoinedResponse(
try!(packet.read_value())
),
CODE_ROOM_USER_LEFT =>
ServerResponse::RoomUserLeftResponse(
try!(packet.read_value())
),
CODE_USER_INFO =>
ServerResponse::UserInfoResponse(
try!(packet.read_value())
),
CODE_USER_STATUS =>
ServerResponse::UserStatusResponse(
try!(packet.read_value())
),
CODE_WISHLIST_INTERVAL =>
ServerResponse::WishlistIntervalResponse(
try!(packet.read_value())
),
CODE_PARENT_MIN_SPEED =>
ServerResponse::ParentMinSpeedResponse(
try!(packet.read_value())
),
CODE_PARENT_SPEED_RATIO =>
ServerResponse::ParentSpeedRatioResponse(
try!(packet.read_value())
),
CODE_CONNECT_TO_PEER => ServerResponse::ConnectToPeerResponse(
try!(packet.read_value()),
),
CODE_FILE_SEARCH => ServerResponse::FileSearchResponse(try!(packet.read_value())),
CODE_LOGIN => ServerResponse::LoginResponse(try!(packet.read_value())),
CODE_PEER_ADDRESS => ServerResponse::PeerAddressResponse(try!(packet.read_value())),
CODE_PRIVILEGED_USERS => ServerResponse::PrivilegedUsersResponse(
try!(packet.read_value()),
),
CODE_ROOM_JOIN => ServerResponse::RoomJoinResponse(try!(packet.read_value())),
CODE_ROOM_LEAVE => ServerResponse::RoomLeaveResponse(try!(packet.read_value())),
CODE_ROOM_LIST => ServerResponse::RoomListResponse(try!(packet.read_value())),
CODE_ROOM_MESSAGE => ServerResponse::RoomMessageResponse(try!(packet.read_value())),
CODE_ROOM_TICKERS => ServerResponse::RoomTickersResponse(try!(packet.read_value())),
CODE_ROOM_USER_JOINED => ServerResponse::RoomUserJoinedResponse(
try!(packet.read_value()),
),
CODE_ROOM_USER_LEFT => ServerResponse::RoomUserLeftResponse(try!(packet.read_value())),
CODE_USER_INFO => ServerResponse::UserInfoResponse(try!(packet.read_value())),
CODE_USER_STATUS => ServerResponse::UserStatusResponse(try!(packet.read_value())),
CODE_WISHLIST_INTERVAL => ServerResponse::WishlistIntervalResponse(
try!(packet.read_value()),
),
CODE_PARENT_MIN_SPEED => ServerResponse::ParentMinSpeedResponse(
try!(packet.read_value()),
),
CODE_PARENT_SPEED_RATIO => ServerResponse::ParentSpeedRatioResponse(
try!(packet.read_value()),
),
code => ServerResponse::UnknownResponse(code),
};
let bytes_remaining = packet.bytes_remaining();
if bytes_remaining > 0 {
warn!("Packet with code {} contains {} extra bytes",
code, bytes_remaining)
warn!(
"Packet with code {} contains {} extra bytes",
code,
bytes_remaining
)
}
Ok(resp)
}
@ -140,30 +104,30 @@ impl ReadFromPacket for ServerResponse {
#[derive(Debug)]
pub struct ConnectToPeerResponse {
pub user_name: String,
pub user_name: String,
pub connection_type: String,
pub ip: net::Ipv4Addr,
pub port: u16,
pub token: u32,
pub is_privileged: bool,
pub ip: net::Ipv4Addr,
pub port: u16,
pub token: u32,
pub is_privileged: bool,
}
impl ReadFromPacket for ConnectToPeerResponse {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let user_name = try!(packet.read_value());
let user_name = try!(packet.read_value());
let connection_type = try!(packet.read_value());
let ip = try!(packet.read_value());
let port = try!(packet.read_value());
let token = try!(packet.read_value());
let is_privileged = try!(packet.read_value());
let ip = try!(packet.read_value());
let port = try!(packet.read_value());
let token = try!(packet.read_value());
let is_privileged = try!(packet.read_value());
Ok(ConnectToPeerResponse {
user_name: user_name,
user_name: user_name,
connection_type: connection_type,
ip: ip,
port: port,
token: token,
is_privileged: is_privileged,
ip: ip,
port: port,
token: token,
is_privileged: is_privileged,
})
}
}
@ -175,20 +139,20 @@ impl ReadFromPacket for ConnectToPeerResponse {
#[derive(Debug)]
pub struct FileSearchResponse {
pub user_name: String,
pub ticket: u32,
pub query: String,
pub ticket: u32,
pub query: String,
}
impl ReadFromPacket for FileSearchResponse {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let user_name = try!(packet.read_value());
let ticket = try!(packet.read_value());
let query = try!(packet.read_value());
let ticket = try!(packet.read_value());
let query = try!(packet.read_value());
Ok(FileSearchResponse {
user_name: user_name,
ticket: ticket,
query: query,
ticket: ticket,
query: query,
})
}
}
@ -202,11 +166,9 @@ pub enum LoginResponse {
LoginOk {
motd: String,
ip: net::Ipv4Addr,
password_md5_opt: Option<String>
},
LoginFail {
reason: String
password_md5_opt: Option<String>,
},
LoginFail { reason: String },
}
impl ReadFromPacket for LoginResponse {
@ -224,11 +186,11 @@ impl ReadFromPacket for LoginResponse {
Ok(LoginResponse::LoginOk {
motd: motd,
ip: ip,
password_md5_opt: None
password_md5_opt: None,
})
} else {
Ok(LoginResponse::LoginFail {
reason: try!(packet.read_value())
reason: try!(packet.read_value()),
})
}
}
@ -246,9 +208,7 @@ pub struct ParentMinSpeedResponse {
impl ReadFromPacket for ParentMinSpeedResponse {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let value = try!(packet.read_value());
Ok(ParentMinSpeedResponse {
value: value,
})
Ok(ParentMinSpeedResponse { value: value })
}
}
@ -264,9 +224,7 @@ pub struct ParentSpeedRatioResponse {
impl ReadFromPacket for ParentSpeedRatioResponse {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let value = try!(packet.read_value());
Ok(ParentSpeedRatioResponse {
value: value,
})
Ok(ParentSpeedRatioResponse { value: value })
}
}
@ -307,9 +265,7 @@ pub struct PrivilegedUsersResponse {
impl ReadFromPacket for PrivilegedUsersResponse {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let users = try!(packet.read_value());
Ok(PrivilegedUsersResponse {
users: users
})
Ok(PrivilegedUsersResponse { users: users })
}
}
@ -338,14 +294,14 @@ impl ReadFromPacket for RoomJoinResponse {
for _ in 0..num_users {
let name = try!(packet.read_value());
let user = user::User {
status: user::Status::Offline,
average_speed: 0,
num_downloads: 0,
unknown: 0,
num_files: 0,
num_folders: 0,
status: user::Status::Offline,
average_speed: 0,
num_downloads: 0,
unknown: 0,
num_files: 0,
num_folders: 0,
num_free_slots: 0,
country: String::new(),
country: String::new(),
};
response.users.push((name, user));
}
@ -366,9 +322,7 @@ impl ReadFromPacket for RoomJoinResponse {
}
impl RoomJoinResponse {
fn read_user_infos(&mut self, packet: &mut Packet)
-> Result<(), PacketReadError>
{
fn read_user_infos(&mut self, packet: &mut Packet) -> Result<(), PacketReadError> {
let num_statuses: usize = try!(packet.read_value());
for i in 0..num_statuses {
if let Some(&mut (_, ref mut user)) = self.users.get_mut(i) {
@ -381,9 +335,9 @@ impl RoomJoinResponse {
if let Some(&mut (_, ref mut user)) = self.users.get_mut(i) {
user.average_speed = try!(packet.read_value());
user.num_downloads = try!(packet.read_value());
user.unknown = try!(packet.read_value());
user.num_files = try!(packet.read_value());
user.num_folders = try!(packet.read_value());
user.unknown = try!(packet.read_value());
user.num_files = try!(packet.read_value());
user.num_folders = try!(packet.read_value());
}
}
@ -402,14 +356,15 @@ impl RoomJoinResponse {
}
let num_users = self.users.len();
if num_users != num_statuses ||
num_users != num_infos ||
num_users != num_free_slots ||
if num_users != num_statuses || num_users != num_infos || num_users != num_free_slots ||
num_users != num_countries
{
warn!(
"RoomJoinResponse: mismatched vector sizes {}, {}, {}, {}, {}",
num_users, num_statuses, num_infos, num_free_slots,
num_users,
num_statuses,
num_infos,
num_free_slots,
num_countries
);
}
@ -429,9 +384,7 @@ pub struct RoomLeaveResponse {
impl ReadFromPacket for RoomLeaveResponse {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
Ok(RoomLeaveResponse {
room_name: try!(packet.read_value()),
})
Ok(RoomLeaveResponse { room_name: try!(packet.read_value()) })
}
}
@ -463,9 +416,7 @@ impl ReadFromPacket for RoomListResponse {
}
impl RoomListResponse {
fn read_rooms(packet: &mut Packet)
-> Result<Vec<(String, u32)>, PacketReadError>
{
fn read_rooms(packet: &mut Packet) -> Result<Vec<(String, u32)>, PacketReadError> {
let num_rooms: usize = try!(packet.read_value());
let mut rooms = Vec::new();
for _ in 0..num_rooms {
@ -483,7 +434,8 @@ impl RoomListResponse {
if num_rooms != num_user_counts {
warn!(
"Numbers of rooms and user counts do not match: {} != {}",
num_rooms, num_user_counts
num_rooms,
num_user_counts
);
}
@ -499,18 +451,18 @@ impl RoomListResponse {
pub struct RoomMessageResponse {
pub room_name: String,
pub user_name: String,
pub message: String,
pub message: String,
}
impl ReadFromPacket for RoomMessageResponse {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let room_name = try!(packet.read_value());
let user_name = try!(packet.read_value());
let message = try!(packet.read_value());
let message = try!(packet.read_value());
Ok(RoomMessageResponse {
room_name: room_name,
user_name: user_name,
message: message,
message: message,
})
}
}
@ -522,7 +474,7 @@ impl ReadFromPacket for RoomMessageResponse {
#[derive(Debug)]
pub struct RoomTickersResponse {
pub room_name: String,
pub tickers: Vec<(String, String)>
pub tickers: Vec<(String, String)>,
}
impl ReadFromPacket for RoomTickersResponse {
@ -533,13 +485,13 @@ impl ReadFromPacket for RoomTickersResponse {
let mut tickers = Vec::new();
for _ in 0..num_tickers {
let user_name = try!(packet.read_value());
let message = try!(packet.read_value());
let message = try!(packet.read_value());
tickers.push((user_name, message))
}
Ok(RoomTickersResponse {
room_name: room_name,
tickers: tickers,
tickers: tickers,
})
}
}
@ -552,7 +504,7 @@ impl ReadFromPacket for RoomTickersResponse {
pub struct RoomUserJoinedResponse {
pub room_name: String,
pub user_name: String,
pub user: user::User,
pub user: user::User,
}
impl ReadFromPacket for RoomUserJoinedResponse {
@ -562,11 +514,11 @@ impl ReadFromPacket for RoomUserJoinedResponse {
let status = try!(packet.read_value());
let average_speed = try!(packet.read_value());
let num_downloads = try!(packet.read_value());
let unknown = try!(packet.read_value());
let num_files = try!(packet.read_value());
let num_folders = try!(packet.read_value());
let average_speed = try!(packet.read_value());
let num_downloads = try!(packet.read_value());
let unknown = try!(packet.read_value());
let num_files = try!(packet.read_value());
let num_folders = try!(packet.read_value());
let num_free_slots = try!(packet.read_value());
let country = try!(packet.read_value());
@ -575,15 +527,15 @@ impl ReadFromPacket for RoomUserJoinedResponse {
room_name: room_name,
user_name: user_name,
user: user::User {
status: status,
average_speed: average_speed,
num_downloads: num_downloads,
unknown: unknown,
num_files: num_files,
num_folders: num_folders,
status: status,
average_speed: average_speed,
num_downloads: num_downloads,
unknown: unknown,
num_files: num_files,
num_folders: num_folders,
num_free_slots: num_free_slots,
country: country,
}
country: country,
},
})
}
}
@ -615,26 +567,26 @@ impl ReadFromPacket for RoomUserLeftResponse {
#[derive(Debug)]
pub struct UserInfoResponse {
pub user_name: String,
pub user_name: String,
pub average_speed: usize,
pub num_downloads: usize,
pub num_files: usize,
pub num_folders: usize,
pub num_files: usize,
pub num_folders: usize,
}
impl ReadFromPacket for UserInfoResponse {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let user_name = try!(packet.read_value());
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());
let num_files = try!(packet.read_value());
let num_folders = try!(packet.read_value());
Ok(UserInfoResponse {
user_name: user_name,
user_name: user_name,
average_speed: average_speed,
num_downloads: num_downloads,
num_files: num_files,
num_folders: num_folders,
num_files: num_files,
num_folders: num_folders,
})
}
}
@ -652,12 +604,12 @@ pub struct UserStatusResponse {
impl ReadFromPacket for UserStatusResponse {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let user_name = try!(packet.read_value());
let status = try!(packet.read_value());
let user_name = try!(packet.read_value());
let status = try!(packet.read_value());
let is_privileged = try!(packet.read_value());
Ok(UserStatusResponse {
user_name: user_name,
status: status,
user_name: user_name,
status: status,
is_privileged: is_privileged,
})
}
@ -675,8 +627,6 @@ pub struct WishlistIntervalResponse {
impl ReadFromPacket for WishlistIntervalResponse {
fn read_from_packet(packet: &mut Packet) -> Result<Self, PacketReadError> {
let seconds = try!(packet.read_value());
Ok(WishlistIntervalResponse {
seconds: seconds,
})
Ok(WishlistIntervalResponse { seconds: seconds })
}
}

+ 27
- 35
src/proto/stream.rs View File

@ -16,14 +16,14 @@ use super::packet::{MutPacket, Parser, ReadFromPacket, WriteToPacket};
#[derive(Debug)]
struct OutBuf {
cursor: usize,
bytes: Vec<u8>
bytes: Vec<u8>,
}
impl From<Vec<u8>> for OutBuf {
fn from(bytes: Vec<u8>) -> Self {
OutBuf {
cursor: 0,
bytes: bytes
bytes: bytes,
}
}
}
@ -40,7 +40,8 @@ impl OutBuf {
}
fn try_write_to<T>(&mut self, mut writer: T) -> io::Result<Option<usize>>
where T: mio::deprecated::TryWrite
where
T: mio::deprecated::TryWrite,
{
let result = writer.try_write(&self.bytes[self.cursor..]);
if let Ok(Some(bytes_written)) = result {
@ -79,39 +80,38 @@ pub enum Intent {
/// This struct wraps around an mio tcp stream and handles packet reads and
/// writes.
#[derive(Debug)]
pub struct Stream<T: SendPacket>
{
pub struct Stream<T: SendPacket> {
parser: Parser,
queue: VecDeque<OutBuf>,
queue: VecDeque<OutBuf>,
sender: T,
stream: mio::tcp::TcpStream,
is_connected: bool,
}
impl<T: SendPacket> Stream<T>
{
impl<T: SendPacket> Stream<T> {
/// Returns a new stream, asynchronously connected to the given address,
/// which forwards incoming packets to the given sender.
/// If an error occurs when connecting, returns an error.
pub fn new<U>(addr_spec: U, sender: T) -> io::Result<Self>
where U: ToSocketAddrs + fmt::Debug
where
U: ToSocketAddrs + fmt::Debug,
{
for sock_addr in try!(addr_spec.to_socket_addrs()) {
if let Ok(stream) = mio::tcp::TcpStream::connect(&sock_addr) {
return Ok(Stream {
parser: Parser::new(),
queue: VecDeque::new(),
queue: VecDeque::new(),
sender: sender,
stream: stream,
is_connected: false,
})
});
}
}
Err(io::Error::new(
io::ErrorKind::Other,
format!("Cannot connect to {:?}", addr_spec)
format!("Cannot connect to {:?}", addr_spec),
))
}
@ -126,21 +126,15 @@ impl<T: SendPacket> Stream<T>
loop {
let mut packet = match self.parser.try_read(&mut self.stream) {
Ok(Some(packet)) => packet,
Ok(None) => {
break
},
Err(e) => {
return Err(format!("Error reading stream: {}", e))
}
Ok(None) => break,
Err(e) => return Err(format!("Error reading stream: {}", e)),
};
let value = match packet.read_value() {
Ok(value) => value,
Err(e) => {
return Err(format!("Error parsing packet: {}", e))
}
Err(e) => return Err(format!("Error parsing packet: {}", e)),
};
if let Err(e) = self.sender.send_packet(value) {
return Err(format!("Error sending parsed packet: {}", e))
return Err(format!("Error sending parsed packet: {}", e));
}
}
Ok(())
@ -151,7 +145,7 @@ impl<T: SendPacket> Stream<T>
loop {
let mut outbuf = match self.queue.pop_front() {
Some(outbuf) => outbuf,
None => break
None => break,
};
let option = try!(outbuf.try_write_to(&mut self.stream));
@ -161,10 +155,10 @@ impl<T: SendPacket> Stream<T>
self.queue.push_front(outbuf)
}
// Continue looping
},
}
None => {
self.queue.push_front(outbuf);
break
break;
}
}
}
@ -174,20 +168,20 @@ impl<T: SendPacket> Stream<T>
/// The stream is ready to read, write, or both.
pub fn on_ready(&mut self, event_set: mio::Ready) -> Intent {
if event_set.is_hup() || event_set.is_error() {
return Intent::Done
return Intent::Done;
}
if event_set.is_readable() {
let result = self.on_readable();
if let Err(e) = result {
error!("Stream input error: {}", e);
return Intent::Done
return Intent::Done;
}
}
if event_set.is_writable() {
let result = self.on_writable();
if let Err(e) = result {
error!("Stream output error: {}", e);
return Intent::Done
return Intent::Done;
}
}
@ -197,17 +191,14 @@ impl<T: SendPacket> Stream<T>
// If we weren't already connected, notify the sink.
if let Err(err) = self.sender.notify_open() {
error!("Cannot notify client that stream is open: {}", err);
return Intent::Done
return Intent::Done;
}
// And record the fact that we are now connected.
self.is_connected = true;
}
// We're always interested in reading more.
let mut event_set =
mio::Ready::readable() |
mio::Ready::hup() |
mio::Ready::error();
let mut event_set = mio::Ready::readable() | mio::Ready::hup() | mio::Ready::error();
// If there is still stuff to write in the queue, we're interested in
// the socket becoming writable too.
if self.queue.len() > 0 {
@ -219,13 +210,14 @@ impl<T: SendPacket> Stream<T>
/// The stream has been notified.
pub fn on_notify<V>(&mut self, payload: &V) -> Intent
where V: WriteToPacket
where
V: WriteToPacket,
{
let mut packet = MutPacket::new();
let result = packet.write_value(payload);
if let Err(e) = result {
error!("Error writing payload to packet: {}", e);
return Intent::Done
return Intent::Done;
}
self.queue.push_back(OutBuf::from(packet.into_bytes()));
Intent::Continue(mio::Ready::readable() | mio::Ready::writable())


+ 62
- 68
src/room.rs View File

@ -37,7 +37,7 @@ pub enum Visibility {
#[derive(Clone, Debug, RustcDecodable, RustcEncodable)]
pub struct Message {
pub user_name: String,
pub message: String,
pub message: String,
}
/// This structure contains the last known information about a chat room.
@ -63,7 +63,7 @@ pub struct Room {
/// The messages sent to this chat room, in chronological order.
pub messages: Vec<Message>,
/// The tickers displayed in this room.
pub tickers: Vec<(String, String)>
pub tickers: Vec<(String, String)>,
}
impl Room {
@ -72,13 +72,13 @@ impl Room {
Room {
membership: Membership::NonMember,
visibility: visibility,
operated: false,
operated: false,
user_count: user_count,
owner: None,
operators: collections::HashSet::new(),
members: collections::HashSet::new(),
messages: Vec::new(),
tickers: Vec::new(),
owner: None,
operators: collections::HashSet::new(),
members: collections::HashSet::new(),
messages: Vec::new(),
tickers: Vec::new(),
}
}
}
@ -93,14 +93,16 @@ pub enum Error {
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::RoomNotFound(ref room_name) =>
write!(f, "room {:?} not found", room_name),
Error::RoomNotFound(ref room_name) => write!(f, "room {:?} not found", room_name),
Error::MembershipChangeInvalid(old_membership, new_membership) =>
Error::MembershipChangeInvalid(old_membership, new_membership) => {
write!(
f, "cannot change membership from {:?} to {:?}",
old_membership, new_membership
),
f,
"cannot change membership from {:?} to {:?}",
old_membership,
new_membership
)
}
}
}
}
@ -109,7 +111,7 @@ impl error::Error for Error {
fn description(&self) -> &str {
match *self {
Error::RoomNotFound(_) => "room not found",
Error::MembershipChangeInvalid(_, _) => "cannot change membership"
Error::MembershipChangeInvalid(_, _) => "cannot change membership",
}
}
}
@ -125,9 +127,7 @@ pub struct RoomMap {
impl RoomMap {
/// Creates an empty mapping.
pub fn new() -> Self {
RoomMap {
map: collections::HashMap::new()
}
RoomMap { map: collections::HashMap::new() }
}
/// Looks up the given room name in the map, returning an immutable
@ -135,7 +135,7 @@ impl RoomMap {
fn get_strict(&self, room_name: &str) -> Result<&Room, Error> {
match self.map.get(room_name) {
Some(room) => Ok(room),
None => Err(Error::RoomNotFound(room_name.to_string()))
None => Err(Error::RoomNotFound(room_name.to_string())),
}
}
@ -144,16 +144,19 @@ impl RoomMap {
fn get_mut_strict(&mut self, room_name: &str) -> Result<&mut Room, Error> {
match self.map.get_mut(room_name) {
Some(room) => Ok(room),
None => Err(Error::RoomNotFound(room_name.to_string()))
None => Err(Error::RoomNotFound(room_name.to_string())),
}
}
/// Updates one room in the map based on the information received in
/// a RoomListResponse and the potential previously stored information.
fn update_one(
&mut self, name: String, visibility: Visibility, user_count: u32,
old_map: &mut collections::HashMap<String, Room>)
{
&mut self,
name: String,
visibility: Visibility,
user_count: u32,
old_map: &mut collections::HashMap<String, Room>,
) {
let room = match old_map.remove(&name) {
None => Room::new(Visibility::Public, user_count as usize),
Some(mut room) => {
@ -171,25 +174,21 @@ impl RoomMap {
/// server response.
pub fn set_room_list(&mut self, mut response: server::RoomListResponse) {
// Replace the old mapping with an empty one.
let mut old_map =
mem::replace(&mut self.map, collections::HashMap::new());
let mut old_map = mem::replace(&mut self.map, collections::HashMap::new());
// Add all public rooms.
for (name, user_count) in response.rooms.drain(..) {
self.update_one(
name, Visibility::Public, user_count, &mut old_map);
self.update_one(name, Visibility::Public, user_count, &mut old_map);
}
// Add all private, owned, rooms.
for (name, user_count) in response.owned_private_rooms.drain(..) {
self.update_one(
name, Visibility::PrivateOwned, user_count, &mut old_map);
self.update_one(name, Visibility::PrivateOwned, user_count, &mut old_map);
}
// Add all private, unowned, rooms.
for (name, user_count) in response.other_private_rooms.drain(..) {
self.update_one(
name, Visibility::PrivateOther, user_count, &mut old_map);
self.update_one(name, Visibility::PrivateOther, user_count, &mut old_map);
}
// Mark all operated rooms as necessary.
@ -202,8 +201,7 @@ impl RoomMap {
}
/// Returns the list of (room name, room data) representing all known rooms.
pub fn get_room_list(&self) -> Vec<(String, Room)>
{
pub fn get_room_list(&self) -> Vec<(String, Room)> {
let mut rooms = Vec::new();
for (room_name, room) in self.map.iter() {
rooms.push((room_name.clone(), room.clone()));
@ -214,21 +212,20 @@ impl RoomMap {
/// Records that we are now trying to join the given room.
/// If the room is not found, or if its membership is not `NonMember`,
/// returns an error.
pub fn start_joining(&mut self, room_name: &str)
-> Result<(), Error>
{
pub fn start_joining(&mut self, room_name: &str) -> Result<(), Error> {
let room = try!(self.get_mut_strict(room_name));
match room.membership {
Membership::NonMember => {
room.membership = Membership::Joining;
Ok(())
},
}
membership => {
Err(Error::MembershipChangeInvalid(
membership, Membership::Joining)
)
membership,
Membership::Joining,
))
}
}
}
@ -236,12 +233,12 @@ impl RoomMap {
/// Records that we are now a member of the given room and updates the room
/// information.
pub fn join(
&mut self, room_name: &str,
&mut self,
room_name: &str,
owner: Option<String>,
mut operators: Vec<String>,
members: &Vec<(String, user::User)>)
-> Result<(), Error>
{
members: &Vec<(String, user::User)>,
) -> Result<(), Error> {
// First look up the room struct.
let room = try!(self.get_mut_strict(room_name));
@ -251,14 +248,15 @@ impl RoomMap {
} else {
warn!(
"Joined room {:?} but membership was already {:?}",
room_name, room.membership
room_name,
room.membership
);
}
// Update the room struct.
room.membership = Membership::Member;
room.user_count = members.len();
room.owner = owner;
room.owner = owner;
room.operators.clear();
for user_name in operators.drain(..) {
@ -276,21 +274,20 @@ impl RoomMap {
/// Records that we are now trying to leave the given room.
/// If the room is not found, or if its membership status is not `Member`,
/// returns an error.
pub fn start_leaving(&mut self, room_name: &str)
-> Result<(), Error>
{
pub fn start_leaving(&mut self, room_name: &str) -> Result<(), Error> {
let room = try!(self.get_mut_strict(room_name));
match room.membership {
Membership::Member => {
room.membership = Membership::Leaving;
Ok(())
},
}
membership => {
Err(Error::MembershipChangeInvalid(
membership, Membership::Leaving)
)
membership,
Membership::Leaving,
))
}
}
}
@ -302,10 +299,13 @@ impl RoomMap {
match room.membership {
Membership::Leaving => info!("Left room {:?}", room_name),
membership => warn!(
"Left room {:?} with wrong membership: {:?}",
room_name, membership
),
membership => {
warn!(
"Left room {:?} with wrong membership: {:?}",
room_name,
membership
)
}
}
room.membership = Membership::NonMember;
@ -313,9 +313,7 @@ impl RoomMap {
}
/// Saves the given message as the last one in the given room.
pub fn add_message(&mut self, room_name: &str, message: Message)
-> Result<(), Error>
{
pub fn add_message(&mut self, room_name: &str, message: Message) -> Result<(), Error> {
let room = try!(self.get_mut_strict(room_name));
room.messages.push(message);
Ok(())
@ -323,9 +321,7 @@ impl RoomMap {
/// Inserts the given user in the given room's set of members.
/// Returns an error if the room is not found.
pub fn insert_member(&mut self, room_name: &str, user_name: String)
-> Result<(), Error>
{
pub fn insert_member(&mut self, room_name: &str, user_name: String) -> Result<(), Error> {
let room = try!(self.get_mut_strict(room_name));
room.members.insert(user_name);
Ok(())
@ -333,9 +329,7 @@ impl RoomMap {
/// Removes the given user from the given room's set of members.
/// Returns an error if the room is not found.
pub fn remove_member(&mut self, room_name: &str, user_name: &str)
-> Result<(), Error>
{
pub fn remove_member(&mut self, room_name: &str, user_name: &str) -> Result<(), Error> {
let room = try!(self.get_mut_strict(room_name));
room.members.remove(user_name);
Ok(())
@ -346,12 +340,12 @@ impl RoomMap {
*---------*/
pub fn set_tickers(
&mut self, room_name: &str, tickers: Vec<(String, String)>)
-> Result<(), Error>
{
&mut self,
room_name: &str,
tickers: Vec<(String, String)>,
) -> Result<(), Error> {
let room = try!(self.get_mut_strict(room_name));
room.tickers = tickers;
Ok(())
}
}

+ 14
- 28
src/user.rs View File

@ -6,8 +6,8 @@ use std::io;
use proto;
const STATUS_OFFLINE: u32 = 1;
const STATUS_AWAY: u32 = 2;
const STATUS_ONLINE: u32 = 3;
const STATUS_AWAY: u32 = 2;
const STATUS_ONLINE: u32 = 3;
/// This enumeration is the list of possible user statuses.
#[derive(Clone, Copy, Debug, RustcDecodable, RustcEncodable)]
@ -21,17 +21,13 @@ pub enum Status {
}
impl proto::ReadFromPacket for Status {
fn read_from_packet(packet: &mut proto::Packet)
-> Result<Self, proto::PacketReadError>
{
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))
}
STATUS_AWAY => Ok(Status::Away),
STATUS_ONLINE => Ok(Status::Online),
_ => Err(proto::PacketReadError::InvalidUserStatusError(n)),
}
}
}
@ -40,8 +36,8 @@ 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,
Status::Away => STATUS_AWAY,
Status::Online => STATUS_ONLINE,
};
try!(packet.write_value(&n));
Ok(())
@ -117,14 +113,10 @@ impl UserMap {
/// 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>
{
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()
})
None => Err(UserNotFoundError { user_name: user_name.to_string() }),
}
}
@ -135,22 +127,17 @@ 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>
{
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(),
})
Err(UserNotFoundError { user_name: user_name.to_string() })
}
}
/// Returns the list of (user name, user data) representing all known users.
pub fn get_list(&self) -> Vec<(String, User)>
{
pub fn get_list(&self) -> Vec<(String, User)> {
let mut users = Vec::new();
for (user_name, user_data) in self.map.iter() {
users.push((user_name.clone(), user_data.clone()));
@ -159,8 +146,7 @@ impl UserMap {
}
/// Sets the set of privileged users to the given list.
pub fn set_all_privileged(&mut self, mut users: Vec<String>)
{
pub fn set_all_privileged(&mut self, mut users: Vec<String>) {
self.privileged.clear();
for user_name in users.drain(..) {
self.privileged.insert(user_name);


Loading…
Cancel
Save