diff --git a/src/cmd/hmap.rs b/src/cmd/hmap.rs index 3f69ace..ab80aee 100644 --- a/src/cmd/hmap.rs +++ b/src/cmd/hmap.rs @@ -1,4 +1,4 @@ -use crate::{Backend, RespArray, RespFrame, RespMap}; +use crate::{Backend, BulkString, RespArray, RespFrame}; use super::{ extract_args, validate_command, CommandError, CommandExecutor, HGet, HGetAll, HSet, RESP_OK, @@ -19,14 +19,20 @@ impl CommandExecutor for HGetAll { match hmap { Some(hmap) => { - let mut map = RespMap::new(); - + let mut data = Vec::with_capacity(hmap.len()); for v in hmap.iter() { let key = v.key().to_owned(); - map.insert(key, v.value().clone()); + data.push((key, v.value().clone())); + } + if self.sort { + data.sort_by(|a, b| a.0.cmp(&b.0)); } + let ret = data + .into_iter() + .flat_map(|(k, v)| vec![BulkString::from(k).into(), v]) + .collect::>(); - map.into() + RespArray::new(ret).into() } None => RespArray::new([]).into(), } @@ -71,6 +77,7 @@ impl TryFrom for HGetAll { match args.next() { Some(RespFrame::BulkString(key)) => Ok(HGetAll { key: String::from_utf8(key.0)?, + sort: false, }), _ => Err(CommandError::InvalidArgument("Invalid key".to_string())), } @@ -177,14 +184,15 @@ mod tests { let cmd = HGetAll { key: "map".to_string(), + sort: true, }; let result = cmd.execute(&backend); - let mut expected = RespMap::new(); - expected.insert("hello".to_string(), RespFrame::BulkString(b"world".into())); - expected.insert( - "hello1".to_string(), - RespFrame::BulkString(b"world1".into()), - ); + let expected = RespArray::new([ + BulkString::from("hello").into(), + BulkString::from("world").into(), + BulkString::from("hello1").into(), + BulkString::from("world1").into(), + ]); assert_eq!(result, expected.into()); Ok(()) } diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs index def7862..a3d3170 100644 --- a/src/cmd/mod.rs +++ b/src/cmd/mod.rs @@ -70,6 +70,7 @@ pub struct HSet { #[derive(Debug)] pub struct HGetAll { key: String, + sort: bool, } #[derive(Debug)] diff --git a/src/resp/bulk_string.rs b/src/resp/bulk_string.rs index 462db6d..e194310 100644 --- a/src/resp/bulk_string.rs +++ b/src/resp/bulk_string.rs @@ -83,6 +83,12 @@ impl From<&str> for BulkString { } } +impl From for BulkString { + fn from(s: String) -> Self { + BulkString(s.into_bytes()) + } +} + impl From<&[u8]> for BulkString { fn from(s: &[u8]) -> Self { BulkString(s.to_vec())