aboutsummaryrefslogtreecommitdiff
path: root/src/resp_parser.rs
diff options
context:
space:
mode:
authoromagdy <omar.professional8777@gmail.com>2025-07-16 22:08:45 +0300
committeromagdy <omar.professional8777@gmail.com>2025-07-16 22:08:45 +0300
commite814746602adf42369abf91882d03b3e16c7c7f0 (patch)
treed9e1c35e80dcbb41d98e3c7e21ec88f9805a5a6f /src/resp_parser.rs
parent18b7911c656b531fc5d7fe15245e765951f3e65e (diff)
downloadredis-rust-e814746602adf42369abf91882d03b3e16c7c7f0.tar.xz
redis-rust-e814746602adf42369abf91882d03b3e16c7c7f0.zip
feat: Added support for simple commands like PING, ECHO, GET and SET
- Implemented a simple parsing logic for parsing commmands now - Created a HashMap that will act as our storage and shared it across threads using `Arc<Mutex<()>>` magic - Wrote some macros to make instantiating RESP types eaiser for myself
Diffstat (limited to 'src/resp_parser.rs')
-rw-r--r--src/resp_parser.rs49
1 files changed, 48 insertions, 1 deletions
diff --git a/src/resp_parser.rs b/src/resp_parser.rs
index a8400d3..bbea0ea 100644
--- a/src/resp_parser.rs
+++ b/src/resp_parser.rs
@@ -495,7 +495,7 @@ fn parse_pushes() {
todo!()
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub enum RespType {
SimpleString(String), // +
SimpleError(String), // -
@@ -514,6 +514,53 @@ pub enum RespType {
Pushes(Vec<RespType>), // >
}
+impl RespType {
+ pub fn to_resp_bytes(&self) -> Vec<u8> {
+ match self {
+ RespType::SimpleString(s) => format!("+{}\r\n", s).into_bytes(),
+ RespType::SimpleError(s) => format!("-{}\r\n", s).into_bytes(),
+ RespType::Integer(i) => format!(":{}\r\n", i).into_bytes(),
+ RespType::BulkString(bytes) => {
+ let len = bytes.len();
+ let s = String::from_utf8_lossy(bytes);
+ format!("${}\r\n{}\r\n", len, s).into_bytes()
+ }
+ RespType::Array(arr) => {
+ let len = arr.len();
+ let elements = arr
+ .iter()
+ .map(|e| e.to_resp_bytes())
+ .collect::<Vec<Vec<u8>>>();
+ // TODO: Implement proper Display for elements because this will definitely not
+ // work
+ format!("*{:?}\r\n{:?}", len, elements).into_bytes()
+ }
+ RespType::Null() => b"_\r\n".into(),
+ RespType::Boolean(b) => format!("#{}\r\n", if *b { "t" } else { "f" }).into_bytes(),
+ RespType::Doubles(d) => format!(",{}\r\n", d).into_bytes(),
+ RespType::BigNumbers(n) => format!("({}\r\n", n).into_bytes(),
+ RespType::BulkErrors(errors) => {
+ todo!()
+ }
+ RespType::VerbatimStrings(strings) => {
+ todo!()
+ }
+ RespType::Maps(map) => {
+ todo!()
+ }
+ RespType::Attributes(attrs) => {
+ todo!()
+ }
+ RespType::Sets(set) => {
+ todo!()
+ }
+ RespType::Pushes(pushes) => {
+ todo!()
+ }
+ }
+ }
+}
+
impl PartialEq for RespType {
fn eq(&self, other: &Self) -> bool {
match (self, other) {