Browse Source

Use thiserror for room errors.

wip
Titouan Rigoudy 4 years ago
parent
commit
187bd36ec6
1 changed files with 31 additions and 53 deletions
  1. +31
    -53
      client/src/room.rs

+ 31
- 53
client/src/room.rs View File

@ -1,10 +1,9 @@
use std::collections;
use std::error;
use std::fmt;
use std::collections::{HashMap, HashSet};
use std::mem; use std::mem;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use solstice_proto::{server, User}; use solstice_proto::{server, User};
use thiserror::Error;
/// 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, Eq, PartialEq, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
@ -57,9 +56,9 @@ pub struct Room {
/// The name of the room's owner, if any. /// The name of the room's owner, if any.
pub owner: Option<String>, pub owner: Option<String>,
/// The names of the room's operators. /// The names of the room's operators.
pub operators: collections::HashSet<String>,
pub operators: HashSet<String>,
/// The names of the room's members. /// The names of the room's members.
pub members: collections::HashSet<String>,
pub members: HashSet<String>,
/// The messages sent to this chat room, in chronological order. /// The messages sent to this chat room, in chronological order.
pub messages: Vec<Message>, pub messages: Vec<Message>,
/// The tickers displayed in this room. /// The tickers displayed in this room.
@ -75,8 +74,8 @@ impl Room {
operated: false, operated: false,
user_count: user_count, user_count: user_count,
owner: None, owner: None,
operators: collections::HashSet::new(),
members: collections::HashSet::new(),
operators: HashSet::new(),
members: HashSet::new(),
messages: Vec::new(), messages: Vec::new(),
tickers: Vec::new(), tickers: Vec::new(),
} }
@ -84,37 +83,13 @@ impl Room {
} }
/// The error returned by RoomMap functions. /// The error returned by RoomMap functions.
#[derive(Debug)]
pub enum Error {
#[derive(Debug, Error)]
pub enum RoomError {
#[error("room {0} not found")]
RoomNotFound(String), RoomNotFound(String),
MembershipChangeInvalid(Membership, Membership),
}
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::MembershipChangeInvalid(old_membership, new_membership) => {
write!(
f,
"cannot change membership from {:?} to {:?}",
old_membership, new_membership
)
}
}
}
}
impl error::Error for Error {
fn description(&self) -> &str {
match *self {
Error::RoomNotFound(_) => "room not found",
Error::MembershipChangeInvalid(_, _) => "cannot change membership",
}
}
#[error("cannot change membership from {0:?} to {1:?}")]
MembershipChangeInvalid(Membership, Membership),
} }
/// Contains the mapping from room names to room data and provides a clean /// Contains the mapping from room names to room data and provides a clean
@ -122,7 +97,7 @@ impl error::Error for Error {
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct RoomMap { pub struct RoomMap {
/// The actual map from room names to room data. /// The actual map from room names to room data.
map: collections::HashMap<String, Room>,
map: HashMap<String, Room>,
} }
impl RoomMap { impl RoomMap {
@ -141,19 +116,22 @@ impl RoomMap {
/// Looks up the given room name in the map, returning an immutable /// Looks up the given room name in the map, returning an immutable
/// reference to the associated data if found, or an error if not found. /// reference to the associated data if found, or an error if not found.
#[cfg(test)] #[cfg(test)]
pub fn get_strict(&self, room_name: &str) -> Result<&Room, Error> {
pub fn get_strict(&self, room_name: &str) -> Result<&Room, RoomError> {
match self.map.get(room_name) { match self.map.get(room_name) {
Some(room) => Ok(room), Some(room) => Ok(room),
None => Err(Error::RoomNotFound(room_name.to_string())),
None => Err(RoomError::RoomNotFound(room_name.to_string())),
} }
} }
/// Looks up the given room name in the map, returning a mutable /// Looks up the given room name in the map, returning a mutable
/// reference to the associated data if found, or an error if not found. /// reference to the associated data if found, or an error if not found.
fn get_mut_strict(&mut self, room_name: &str) -> Result<&mut Room, Error> {
fn get_mut_strict(
&mut self,
room_name: &str,
) -> Result<&mut Room, RoomError> {
match self.map.get_mut(room_name) { match self.map.get_mut(room_name) {
Some(room) => Ok(room), Some(room) => Ok(room),
None => Err(Error::RoomNotFound(room_name.to_string())),
None => Err(RoomError::RoomNotFound(room_name.to_string())),
} }
} }
@ -164,7 +142,7 @@ impl RoomMap {
name: String, name: String,
visibility: Visibility, visibility: Visibility,
user_count: u32, user_count: u32,
old_map: &mut collections::HashMap<String, Room>,
old_map: &mut HashMap<String, Room>,
) { ) {
let room = match old_map.remove(&name) { let room = match old_map.remove(&name) {
None => Room::new(Visibility::Public, user_count as usize), None => Room::new(Visibility::Public, user_count as usize),
@ -183,7 +161,7 @@ impl RoomMap {
/// server response. /// server response.
pub fn set_room_list(&mut self, mut response: server::RoomListResponse) { pub fn set_room_list(&mut self, mut response: server::RoomListResponse) {
// Replace the old mapping with an empty one. // 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, HashMap::new());
// Add all public rooms. // Add all public rooms.
for (name, user_count) in response.rooms.drain(..) { for (name, user_count) in response.rooms.drain(..) {
@ -221,7 +199,7 @@ impl RoomMap {
/// Records that we are now trying to join the given room. /// Records that we are now trying to join the given room.
/// If the room is not found, or if its membership is not `NonMember`, /// If the room is not found, or if its membership is not `NonMember`,
/// returns an error. /// returns an error.
pub fn start_joining(&mut self, room_name: &str) -> Result<(), Error> {
pub fn start_joining(&mut self, room_name: &str) -> Result<(), RoomError> {
let room = self.get_mut_strict(room_name)?; let room = self.get_mut_strict(room_name)?;
match room.membership { match room.membership {
@ -230,7 +208,7 @@ impl RoomMap {
Ok(()) Ok(())
} }
membership => Err(Error::MembershipChangeInvalid(
membership => Err(RoomError::MembershipChangeInvalid(
membership, membership,
Membership::Joining, Membership::Joining,
)), )),
@ -245,7 +223,7 @@ impl RoomMap {
owner: Option<String>, owner: Option<String>,
mut operators: Vec<String>, mut operators: Vec<String>,
members: &[User], members: &[User],
) -> Result<&Room, Error> {
) -> Result<&Room, RoomError> {
// First look up the room struct. // First look up the room struct.
let room = self.get_mut_strict(room_name)?; let room = self.get_mut_strict(room_name)?;
@ -280,7 +258,7 @@ impl RoomMap {
/// Records that we are now trying to leave the given room. /// 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`, /// If the room is not found, or if its membership status is not `Member`,
/// returns an error. /// returns an error.
pub fn start_leaving(&mut self, room_name: &str) -> Result<(), Error> {
pub fn start_leaving(&mut self, room_name: &str) -> Result<(), RoomError> {
let room = self.get_mut_strict(room_name)?; let room = self.get_mut_strict(room_name)?;
match room.membership { match room.membership {
@ -289,7 +267,7 @@ impl RoomMap {
Ok(()) Ok(())
} }
membership => Err(Error::MembershipChangeInvalid(
membership => Err(RoomError::MembershipChangeInvalid(
membership, membership,
Membership::Leaving, Membership::Leaving,
)), )),
@ -297,7 +275,7 @@ impl RoomMap {
} }
/// Records that we have now left the given room. /// Records that we have now left the given room.
pub fn leave(&mut self, room_name: &str) -> Result<(), Error> {
pub fn leave(&mut self, room_name: &str) -> Result<(), RoomError> {
let room = self.get_mut_strict(room_name)?; let room = self.get_mut_strict(room_name)?;
match room.membership { match room.membership {
@ -318,7 +296,7 @@ impl RoomMap {
&mut self, &mut self,
room_name: &str, room_name: &str,
message: Message, message: Message,
) -> Result<(), Error> {
) -> Result<(), RoomError> {
let room = self.get_mut_strict(room_name)?; let room = self.get_mut_strict(room_name)?;
room.messages.push(message); room.messages.push(message);
Ok(()) Ok(())
@ -330,7 +308,7 @@ impl RoomMap {
&mut self, &mut self,
room_name: &str, room_name: &str,
user_name: String, user_name: String,
) -> Result<(), Error> {
) -> Result<(), RoomError> {
let room = self.get_mut_strict(room_name)?; let room = self.get_mut_strict(room_name)?;
room.members.insert(user_name); room.members.insert(user_name);
Ok(()) Ok(())
@ -342,7 +320,7 @@ impl RoomMap {
&mut self, &mut self,
room_name: &str, room_name: &str,
user_name: &str, user_name: &str,
) -> Result<(), Error> {
) -> Result<(), RoomError> {
let room = self.get_mut_strict(room_name)?; let room = self.get_mut_strict(room_name)?;
room.members.remove(user_name); room.members.remove(user_name);
Ok(()) Ok(())
@ -356,7 +334,7 @@ impl RoomMap {
&mut self, &mut self,
room_name: &str, room_name: &str,
tickers: Vec<(String, String)>, tickers: Vec<(String, String)>,
) -> Result<(), Error> {
) -> Result<(), RoomError> {
let room = self.get_mut_strict(room_name)?; let room = self.get_mut_strict(room_name)?;
room.tickers = tickers; room.tickers = tickers;
Ok(()) Ok(())


Loading…
Cancel
Save