aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoromagdy <omar.professional8777@gmail.com>2025-07-16 06:42:23 +0300
committeromagdy <omar.professional8777@gmail.com>2025-07-16 06:42:23 +0300
commit18b7911c656b531fc5d7fe15245e765951f3e65e (patch)
tree31e3d9323f9458ed0c0efb0922098a590f61717e
parenta312e41beb06a59a3842ffe56a5d04c3cbef092c (diff)
downloadredis-rust-18b7911c656b531fc5d7fe15245e765951f3e65e.tar.xz
redis-rust-18b7911c656b531fc5d7fe15245e765951f3e65e.zip
feat: Finished ECHO command
-rw-r--r--src/main.rs13
-rw-r--r--src/resp_commands.rs59
2 files changed, 70 insertions, 2 deletions
diff --git a/src/main.rs b/src/main.rs
index c3a88b0..7ddd478 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,17 +5,26 @@ use std::{
thread,
};
+mod resp_commands;
+mod resp_parser;
+
+use resp_commands::RespCommands;
+use resp_parser::parse;
+
fn handle_client(mut stream: TcpStream) {
let mut buffer = [0; 512];
loop {
- let _bytes_read = match stream.read(&mut buffer) {
+ let bytes_read = match stream.read(&mut buffer) {
Ok(0) => return, // connection closed
Ok(n) => n,
Err(_) => return, // error occurred
};
+ let parsed_resp = parse(&buffer).unwrap();
+ let response = RespCommands::from(parsed_resp.0).execute();
+
// Hardcode PONG response for now
- stream.write(b"+PONG\r\n").unwrap();
+ stream.write(&response).unwrap();
// Echo the message back
// if let Err(_) = stream.write_all(&buffer[..bytes_read]) {
diff --git a/src/resp_commands.rs b/src/resp_commands.rs
new file mode 100644
index 0000000..82c0079
--- /dev/null
+++ b/src/resp_commands.rs
@@ -0,0 +1,59 @@
+use crate::resp_parser::*;
+
+pub enum RespCommands {
+ PING,
+ ECHO(String),
+ GET(String),
+ SET(String),
+ Invalid,
+}
+
+impl RespCommands {
+ pub fn execute(self) -> Vec<u8> {
+ match self {
+ RespCommands::PING => b"+PONG\r\n".to_vec(),
+ RespCommands::ECHO(echo_string) => echo_string.into_bytes(),
+ RespCommands::GET(_) => todo!(),
+ RespCommands::SET(_) => todo!(),
+ RespCommands::Invalid => todo!(),
+ }
+ }
+}
+
+impl From<RespType> for RespCommands {
+ fn from(value: RespType) -> Self {
+ match value {
+ RespType::Array(vec) if vec.len() > 1 => match (&vec[0], &vec[1]) {
+ (RespType::BulkString(command), RespType::BulkString(argument)) => {
+ if let Ok(command) = str::from_utf8(&command) {
+ match command {
+ "PING" => Self::PING,
+ "ECHO" => Self::ECHO(format!(
+ "+{}\r\n",
+ String::from_utf8(argument.clone()).unwrap()
+ )),
+ _ => Self::Invalid,
+ }
+ } else {
+ Self::Invalid
+ }
+ }
+ _ => todo!(),
+ },
+ RespType::Array(vec) => match &vec[0] {
+ RespType::BulkString(command) => {
+ if let Ok(command) = str::from_utf8(&command) {
+ match command {
+ "PING" => Self::PING,
+ _ => Self::Invalid,
+ }
+ } else {
+ Self::Invalid
+ }
+ }
+ _ => Self::Invalid,
+ },
+ _ => todo!(),
+ }
+ }
+}