use crate::{
Result,
resp::{RespBatchDeserializer, RespFrameParser, RespResponse, RespTapeMut},
};
use bytes::Bytes;
use serde::de::DeserializeOwned;
fn parse(resp: &'static [u8]) -> RespResponse {
let resp = Bytes::from_static(resp);
let mut tape = RespTapeMut::default();
let mut parser = RespFrameParser::new(&resp, &mut tape);
let (frame, _) = parser.parse().unwrap();
RespResponse::new(resp.into(), frame)
}
fn read<T: DeserializeOwned>(replies: &[&'static [u8]]) -> Result<T> {
let responses: Vec<RespResponse> = replies.iter().copied().map(parse).collect();
let deserializer = RespBatchDeserializer::new(&responses);
T::deserialize(&deserializer)
}
#[test]
fn one_reply_reads_as_a_one_element_collection() -> Result<()> {
let values: Vec<Option<i64>> = read(&[b"$1\r\n1\r\n"])?;
assert_eq!(vec![Some(1)], values);
let values: Vec<Option<i64>> = read(&[b"_\r\n"])?;
assert_eq!(vec![None], values);
let values: Vec<String> = read(&[b"$6\r\nvalue1\r\n"])?;
assert_eq!(vec!["value1".to_owned()], values);
Ok(())
}
#[test]
fn one_reply_still_reads_as_the_scalar() -> Result<()> {
let value: Option<i64> = read(&[b"$1\r\n1\r\n"])?;
assert_eq!(Some(1), value);
let value: Option<i64> = read(&[b"_\r\n"])?;
assert_eq!(None, value);
let value: i64 = read(&[b":42\r\n"])?;
assert_eq!(42, value);
let value: String = read(&[b"$6\r\nvalue1\r\n"])?;
assert_eq!("value1", value);
let value: bool = read(&[b"#t\r\n"])?;
assert!(value);
Ok(())
}
#[test]
fn one_reply_reads_as_a_one_element_tuple() -> Result<()> {
let (value,): (String,) = read(&[b"+OK\r\n"])?;
assert_eq!("OK", value);
let (array,): (Vec<String>,) = read(&[b"*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"])?;
assert_eq!(vec!["foo".to_owned(), "bar".to_owned()], array);
Ok(())
}
#[test]
fn several_replies_read_as_the_batch() -> Result<()> {
let (value1, value2): (String, String) = read(&[b"$6\r\nvalue1\r\n", b"$6\r\nvalue2\r\n"])?;
assert_eq!("value1", value1);
assert_eq!("value2", value2);
let values: Vec<Option<i64>> = read(&[b"$1\r\n1\r\n", b"_\r\n"])?;
assert_eq!(vec![Some(1), None], values);
Ok(())
}
#[test]
fn an_empty_batch_reads_as_the_unit() -> Result<()> {
read::<()>(&[])?;
let values: Vec<String> = read(&[])?;
assert!(values.is_empty());
Ok(())
}
#[test]
fn an_error_reply_is_surfaced_whichever_form_reads_it() {
read::<()>(&[b"-ERR boom\r\n"]).expect_err("the unit reading must surface the error");
read::<Vec<i64>>(&[b"-ERR boom\r\n"]).expect_err("the collection reading must surface it too");
read::<i64>(&[b"-ERR boom\r\n"]).expect_err("the scalar reading must surface it too");
}