Skip to content

Commit d236736

Browse files
authored
Merge pull request #29 from augustuswm/hashmap
Add FromResp impl for HashMap
2 parents f4fecb2 + ff50589 commit d236736

File tree

1 file changed

+64
-1
lines changed

1 file changed

+64
-1
lines changed

src/resp.rs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
//! An implementation of the RESP protocol
1212
13+
use std::collections::HashMap;
14+
use std::hash::Hash;
1315
use std::io;
1416
use std::str;
1517

@@ -187,6 +189,30 @@ impl<T: FromResp> FromResp for Vec<T> {
187189
}
188190
}
189191

192+
impl<K: FromResp + Hash + Eq, T: FromResp> FromResp for HashMap<K, T> {
193+
fn from_resp_int(resp: RespValue) -> Result<HashMap<K, T>, Error> {
194+
match resp {
195+
RespValue::Array(ary) => {
196+
let mut map = HashMap::new();
197+
let mut items = ary.into_iter();
198+
199+
while let Some(k) = items.next() {
200+
let key = K::from_resp(k)?;
201+
let value = T::from_resp(items.next().ok_or(error::resp(
202+
"Cannot convert an odd number of elements into a hashmap",
203+
"".into(),
204+
))?)?;
205+
206+
map.insert(key, value);
207+
}
208+
209+
Ok(map)
210+
}
211+
_ => Err(error::resp("Cannot be converted into a hashmap", resp)),
212+
}
213+
}
214+
}
215+
190216
impl FromResp for () {
191217
fn from_resp_int(resp: RespValue) -> Result<(), Error> {
192218
match resp {
@@ -613,11 +639,13 @@ impl Decoder for RespCodec {
613639

614640
#[cfg(test)]
615641
mod tests {
642+
use std::collections::HashMap;
643+
616644
use bytes::BytesMut;
617645

618646
use tokio_io::codec::{Decoder, Encoder};
619647

620-
use super::{FromResp, RespCodec, RespValue};
648+
use super::{Error, FromResp, RespCodec, RespValue};
621649

622650
#[test]
623651
fn test_bulk_string() {
@@ -675,4 +703,39 @@ mod tests {
675703
let resp_object = RespValue::Integer(50);
676704
assert_eq!(u32::from_resp(resp_object).unwrap(), 50);
677705
}
706+
707+
#[test]
708+
fn test_hashmap_conversion() {
709+
let mut expected = HashMap::new();
710+
expected.insert("KEY1".to_string(), "VALUE1".to_string());
711+
expected.insert("KEY2".to_string(), "VALUE2".to_string());
712+
713+
let resp_object = RespValue::Array(vec![
714+
"KEY1".into(),
715+
"VALUE1".into(),
716+
"KEY2".into(),
717+
"VALUE2".into(),
718+
]);
719+
assert_eq!(
720+
HashMap::<String, String>::from_resp(resp_object).unwrap(),
721+
expected
722+
);
723+
}
724+
725+
#[test]
726+
fn test_hashmap_conversion_fails_with_odd_length_array() {
727+
let resp_object = RespValue::Array(vec![
728+
"KEY1".into(),
729+
"VALUE1".into(),
730+
"KEY2".into(),
731+
"VALUE2".into(),
732+
"KEY3".into(),
733+
]);
734+
let res = HashMap::<String, String>::from_resp(resp_object);
735+
736+
match res {
737+
Err(Error::RESP(_, _)) => {}
738+
_ => panic!("Should not be able to convert an odd number of elements to a hashmap"),
739+
}
740+
}
678741
}

0 commit comments

Comments
 (0)