From 980b87ff4e7c182f2097b547e92c07da799827ee Mon Sep 17 00:00:00 2001 From: robinsonweng Date: Sat, 6 Jan 2024 12:38:43 +0800 Subject: [PATCH] refactor: Create a interface for both server & mocked server --- src/irc/command.rs | 26 +++++++++++++------- src/irc/server.rs | 60 +++++++++++++++++++++++++++++++++------------- src/main.rs | 6 ++--- 3 files changed, 64 insertions(+), 28 deletions(-) diff --git a/src/irc/command.rs b/src/irc/command.rs index c9aab55..086d41d 100644 --- a/src/irc/command.rs +++ b/src/irc/command.rs @@ -1,5 +1,5 @@ use crate::irc::response::{IrcError, IrcErrors, IrcReply, IrcResponseToMessage}; -use crate::irc::server::{Server, UserStatus}; +use crate::irc::server::{IrcServer, UserStatus, Server}; use regex::Regex; use std::io::Write; use std::net::{SocketAddr, TcpStream}; @@ -69,7 +69,7 @@ impl CommandHandler { pub fn execute( &self, stream: &mut TcpStream, - server: &mut Server, + server: &mut IrcServer, client_ip: SocketAddr, ) -> Result<(), IrcErrors> { // if first user detected in NICK command, wait untill user occor @@ -200,7 +200,7 @@ impl CommandHandler { pub fn user_online( &self, stream: &mut TcpStream, - server: &mut Server, + server: &mut IrcServer, hostname: &str, client_ip: SocketAddr, ) -> std::io::Result<()> { @@ -239,7 +239,7 @@ impl CommandHandler { pub fn set_nickname( &self, - server: &mut Server, + server: &mut IrcServer, nickname: &str, source_ip: SocketAddr, ) -> Result<(), IrcError> { @@ -248,21 +248,21 @@ impl CommandHandler { result } - pub fn set_realname(&self, server: &mut Server, source_ip: SocketAddr, realname: &str) { + pub fn set_realname(&self, server: &mut IrcServer, source_ip: SocketAddr, realname: &str) { server.set_realname_by_ip(source_ip, realname); } - pub fn set_username(&self, server: &mut Server, source_ip: SocketAddr, username: &str) { + pub fn set_username(&self, server: &mut IrcServer, source_ip: SocketAddr, username: &str) { server.set_username_by_ip(source_ip, username); } - pub fn set_user_status(&self, server: &mut Server, source_ip: SocketAddr, status: UserStatus) { + pub fn set_user_status(&self, server: &mut IrcServer, source_ip: SocketAddr, status: UserStatus) { server.set_user_status_by_ip(source_ip, status); } pub fn is_user_ready_to_register( &self, - server: &mut Server, + server: &mut IrcServer, source_ip: SocketAddr, ) -> Option { if !server.is_user_ready_to_register(source_ip) { @@ -275,6 +275,11 @@ impl CommandHandler { #[cfg(test)] mod command_tests { use super::*; + use std::net::{IpAddr, Ipv4Addr}; + + struct MockServer { + + } pub fn setup(raw_message: &str) -> CommandHandler { CommandHandler::new(raw_message) @@ -283,7 +288,12 @@ mod command_tests { #[test] fn test_execute_command_new_nickname() { let raw_message = "NICK Wiz"; + let client_ip = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 1234); + let mut server = IrcServer::new(); + let mut stream: TcpStream; + let command_handler = setup(raw_message); + // command_handler.execute(&mut stream, &mut server, client_ip); } fn test_execute_command_change_nickname() { let raw_message = ":WiZ NICK Kilroy"; diff --git a/src/irc/server.rs b/src/irc/server.rs index f5244dd..34b1f89 100644 --- a/src/irc/server.rs +++ b/src/irc/server.rs @@ -47,33 +47,47 @@ pub struct Channel { user_amount: u64, } -pub struct Server { +pub struct IrcServer { online_users: Vec, } -impl PartialEq for Server { +pub trait Server { + fn new() -> Self; + fn user_online(&mut self, source_ip: SocketAddr); + fn user_offline(&mut self, source_ip: SocketAddr); + fn is_nickname_collision(&self, nickname: &str) -> bool; + fn get_user_status(&mut self, source_ip: SocketAddr) -> UserStatus; + fn get_user_nick(&mut self, source_ip: SocketAddr) -> String; + fn set_user_status_by_ip(&mut self, source_ip: SocketAddr, status: UserStatus); + fn is_user_ready_to_register(&mut self, source_ip: SocketAddr) -> bool; + fn set_user_nickname_by_ip(&mut self, source_ip: SocketAddr, nickname: &str) -> Result<(), IrcError>; + fn set_realname_by_ip(&mut self, source_ip: SocketAddr, realname: &str); + fn set_username_by_ip(&mut self, source_ip: SocketAddr, username: &str); +} + +impl PartialEq for IrcServer { fn eq(&self, other: &Self) -> bool { self.online_users == other.online_users } } -impl Eq for Server {} +impl Eq for IrcServer {} -impl Server { - pub fn new() -> Self { +impl Server for IrcServer { + fn new() -> Self { Self { online_users: Vec::new(), } } - pub fn user_online(&mut self, source_ip: SocketAddr) { + fn user_online(&mut self, source_ip: SocketAddr) { // self.online_users.contains(user) let user = User::new(source_ip); println!("User: {:?} online!", user); self.online_users.push(user); } - pub fn user_offline(&mut self, source_ip: SocketAddr) { + fn user_offline(&mut self, source_ip: SocketAddr) { let index = self .online_users .iter() @@ -84,7 +98,7 @@ impl Server { self.online_users.remove(index); } - pub fn is_nickname_collision(&self, nickname: &str) -> bool { + fn is_nickname_collision(&self, nickname: &str) -> bool { for user in &self.online_users { if nickname.to_string() == user.nickname { return true; @@ -93,7 +107,7 @@ impl Server { false } - pub fn get_user_status(&mut self, source_ip: SocketAddr) -> UserStatus { + fn get_user_status(&mut self, source_ip: SocketAddr) -> UserStatus { let index = &self .online_users .iter() @@ -103,7 +117,7 @@ impl Server { self.online_users[*index].status } - pub fn get_user_nick(&mut self, source_ip: SocketAddr) -> String { + fn get_user_nick(&mut self, source_ip: SocketAddr) -> String { let index = &self .online_users .iter() @@ -113,7 +127,11 @@ impl Server { self.online_users[*index].nickname.clone() } - pub fn set_user_status_by_ip(&mut self, source_ip: SocketAddr, status: UserStatus) { + fn set_user_status_by_ip( + &mut self, + source_ip: SocketAddr, + status: UserStatus +) { let index = &self .online_users .iter() @@ -132,7 +150,7 @@ impl Server { self.online_users.push(user); } - pub fn is_user_ready_to_register(&mut self, source_ip: SocketAddr) -> bool { + fn is_user_ready_to_register(&mut self, source_ip: SocketAddr) -> bool { let index = &self .online_users .iter() @@ -149,7 +167,7 @@ impl Server { false } - pub fn set_user_nickname_by_ip( + fn set_user_nickname_by_ip( &mut self, source_ip: SocketAddr, nickname: &str, @@ -181,7 +199,11 @@ impl Server { Ok(()) } - pub fn set_realname_by_ip(&mut self, source_ip: SocketAddr, realname: &str) { + fn set_realname_by_ip( + &mut self, + source_ip: SocketAddr, + realname: &str + ) { let target_index = &self .online_users .iter() @@ -202,7 +224,11 @@ impl Server { self.online_users.push(user); } - pub fn set_username_by_ip(&mut self, source_ip: SocketAddr, username: &str) { + fn set_username_by_ip( + &mut self, + source_ip: SocketAddr, + username: &str + ) { let target_index = &self .online_users .iter() @@ -228,8 +254,8 @@ mod server_unit_tests { use super::*; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; - pub fn setup() -> Server { - Server::new() + pub fn setup() -> IrcServer { + IrcServer::new() } #[test] diff --git a/src/main.rs b/src/main.rs index 55aad59..75ff601 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,13 +6,13 @@ use std::time::Duration; mod irc; use irc::command::CommandHandler; use irc::response::IrcErrors; -use irc::server::Server; +use irc::server::{IrcServer, Server}; const READ_TIMEOUT: (u64, u32) = (20, 0); const WRITE_TIMEOUT: (u64, u32) = (20, 0); const HOST_NAME: &'static str = "localhost"; -fn handle_event(tcp_stream: TcpStream, server: &mut Server) -> std::io::Result<()> { +fn handle_event(tcp_stream: TcpStream, server: &mut IrcServer) -> std::io::Result<()> { let mut stream = tcp_stream; let client_ip = stream.peer_addr()?; let host_ip = stream.local_addr()?; @@ -64,7 +64,7 @@ fn main() -> std::io::Result<()> { let socket_ip = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 6667); let listener = TcpListener::bind(socket_ip)?; - let mut server = Server::new(); + let mut server = IrcServer::new(); for stream in listener.incoming() { let client = stream?; handle_event(client, &mut server)?;