From d0cc82d9d1a80ac8d95e5b29d435b7390a9cbb4e Mon Sep 17 00:00:00 2001 From: leonidchashnikov Date: Mon, 22 Apr 2024 20:17:19 +0100 Subject: [PATCH] Change Command implementation from trait to enum --- src/server/commands.rs | 57 ++++++++++++++++++++++++++++--------- src/server/control_plane.rs | 24 +++++----------- src/server/listener.rs | 5 ++-- src/server/test_mode.rs | 5 ++-- 4 files changed, 57 insertions(+), 34 deletions(-) diff --git a/src/server/commands.rs b/src/server/commands.rs index aa977cd..d81c076 100644 --- a/src/server/commands.rs +++ b/src/server/commands.rs @@ -1,30 +1,33 @@ -pub trait Command { - // fn execute(&self); +pub enum CommandEnum { + PutCommand(Put), + GetCommand(Get), + ExistsCommand(Exists), + ExitCommand(Exit), } // Define concrete command types pub struct Put { - key: String, - value: String, + pub key: String, + pub value: String, } pub struct Get { - key: String, + pub key: String, } pub struct Exists { - key: String, + pub key: String, } pub struct Exit {} -impl Command for Put {} - -impl Command for Get {} - -impl Command for Exists {} - -impl Command for Exit {} +// impl Command for PutCommand {} +// +// impl Command for GetCommand {} +// +// impl Command for ExistsCommand {} +// +// impl Command for ExitCommand {} pub trait CommandResponse { @@ -81,3 +84,31 @@ impl CommandResponse for CommandNotFoundResponse { return String::from("Command not found"); } } + +pub fn deserialize_command(input: String) -> CommandEnum { + let parts: Vec<&str> = input.split_whitespace().collect(); + let command = parts.get(0); + + return match command { + Some(&"set") => { + let key = String::from(parts[1]); + let value = String::from(parts[2]); + CommandEnum::PutCommand(Put { key, value }) + } + Some(&"get") => { + let key = String::from(parts[1]); + CommandEnum::GetCommand(Get { key }) + } + Some(&"exists") => { + let key = String::from(parts[1]); + CommandEnum::ExistsCommand(Exists { key }) + } + Some(&"exit") => { + CommandEnum::ExitCommand(Exit {}) + } + _ => { + // TODO: proper handling + panic!("Command {command:#?} not found."); + } + }; +} \ No newline at end of file diff --git a/src/server/control_plane.rs b/src/server/control_plane.rs index 7dbe232..09f83d4 100644 --- a/src/server/control_plane.rs +++ b/src/server/control_plane.rs @@ -1,21 +1,16 @@ use log::warn; use crate::server::cache::Cache; use crate::server::commands; +use crate::server::commands::CommandEnum; -pub fn process_command(input: &String, cache: &mut Cache) -> Box { - let parts: Vec<&str> = input.split_whitespace().collect(); - let command = parts.get(0); - +pub fn process_command(command: CommandEnum, cache: &mut Cache) -> Box { return match command { - Some(&"set") => { - let key = String::from(parts[1]); - let value = String::from(parts[2]); + CommandEnum::PutCommand(commands::Put { key, value }) => { cache.put(&key, &value); let response = commands::PutResponse {}; - Box::new(response) // "Called set with: {key} -> {value}"); + Box::new(response) } - Some(&"get") => { - let key = String::from(parts[1]); + CommandEnum::GetCommand(commands::Get { key }) => { let value = cache.get(&key).map(|s| s.clone()); let response = commands::GetResponse { key, @@ -23,19 +18,14 @@ pub fn process_command(input: &String, cache: &mut Cache) -> Box { - let key = String::from(parts[1]); + CommandEnum::ExistsCommand(commands::Exists { key }) => { let exists = cache.exists(&key); let response = commands::ExistsResponse { exists }; Box::new(response) } - Some(&"exit") => { + CommandEnum::ExitCommand(commands::Exit {}) => { warn!("Received EXIT command. Wrapping up."); panic!("Received EXIT command"); } - _ => { - warn!("Command {command:#?} not found."); - Box::new(commands::CommandNotFoundResponse {}) - } }; } \ No newline at end of file diff --git a/src/server/listener.rs b/src/server/listener.rs index 6329247..79d2f51 100644 --- a/src/server/listener.rs +++ b/src/server/listener.rs @@ -4,7 +4,7 @@ use std::sync::{Arc, Mutex}; use log::info; use rayon::ThreadPoolBuilder; use crate::server::cache::Cache; -use crate::server::control_plane; +use crate::server::{commands, control_plane}; pub fn start_listener(cache: Cache) { let port = 7878;// &args[2]; @@ -28,9 +28,10 @@ fn handle_connection(stream: TcpStream, cache: Arc>) { let mut s = String::new(); reader.read_line(&mut s).unwrap(); info!("Received command: {s}"); + let command = commands::deserialize_command(s); let mut cache = cache.lock().unwrap(); - let response = control_plane::process_command(&s, &mut cache); + let response = control_plane::process_command(command, &mut cache); let mut response_str = response.serialize(); response_str.push_str("\n"); diff --git a/src/server/test_mode.rs b/src/server/test_mode.rs index ca31564..6d4388d 100644 --- a/src/server/test_mode.rs +++ b/src/server/test_mode.rs @@ -1,7 +1,7 @@ use std::io; use log::info; use crate::server::cache::Cache; -use crate::server::control_plane; +use crate::server::{commands, control_plane}; pub fn run_test_mode(mut cache: Cache) { @@ -11,6 +11,7 @@ pub fn run_test_mode(mut cache: Cache) { io::stdin() .read_line(&mut input) .expect("Failed to read line"); - control_plane::process_command(&input, &mut cache); + let command = commands::deserialize_command(input); + control_plane::process_command(command, &mut cache); } }