use crate::api::client::{ApiError, Client}; use crate::room::Room; use std::fmt; #[derive(Debug, PartialEq, Eq)] enum UserInitErrorReason { InvalidUsername, NoDomainProvided, } #[derive(Debug, PartialEq)] struct UserInitError { message: String, reason: UserInitErrorReason, } impl UserInitError { fn new(msg: &str, reason: UserInitErrorReason) -> Self { UserInitError { message: msg.to_string(), reason, } } } impl fmt::Display for UserInitError { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "{}", self.message) } } #[derive(Debug)] struct User { id: String, display_name: Option, client: Client, } impl PartialEq for User { fn eq(&self, rhs: &Self) -> bool { self.id == rhs.id && self.display_name == rhs.display_name } } impl User { /// Constructs a new User. This represents a user in a room. /// /// # Arguments /// - `id` - The fully qualified user id, following the form @user:domain. Currently, this only /// checks whether the id starts with `@` and contains a `:`. /// - `display_name` - Some display name to use??? TODO: Figure out what this does /// /// Returns either a new User struct or an error containing the reason why it failed to create a /// new User. pub fn new( client: Client, id: String, display_name: Option, ) -> Result { if !id.starts_with("@") { Err(UserInitError::new( "User ID must start with a @", UserInitErrorReason::InvalidUsername, )) } else if !id.contains(":") { Err(UserInitError::new( "User ID must contain a :", UserInitErrorReason::NoDomainProvided, )) } else { Ok(User { id, display_name, client, }) } } fn get_display_name(room: Room) -> String { unimplemented!() } fn set_display_name(&mut self, name: &str) -> Result<(), ApiError> { unimplemented!() } fn get_avatar_url() -> Result { unimplemented!() } fn set_avatar_url(url: &str) -> Result<(), ApiError> { unimplemented!() } } #[cfg(test)] mod tests { use super::*; #[test] fn new_returns_err_on_invalid_id() { assert_eq!( User::new( Client::new("https://google.com", None, None, None, None).unwrap(), String::from("abc:edf"), None ), Err(UserInitError { message: "User ID must start with a @".to_string(), reason: UserInitErrorReason::InvalidUsername }) ); assert_eq!( User::new( Client::new("https://google.com", None, None, None, None).unwrap(), String::from("@abcedf"), None ), Err(UserInitError { message: "User ID must contain a :".to_string(), reason: UserInitErrorReason::NoDomainProvided }) ); } #[test] fn new_returns_struct_on_valid_input() { assert_eq!( User::new( Client::new("https://google.com", None, None, None, None).unwrap(), "@eddie:eddie.sh".to_string(), None ), Ok(User { id: "@eddie:eddie.sh".to_string(), display_name: None, client: Client::new("https://google.com", None, None, None, None).unwrap() }) ) } }