From 330a8f513ad514bd82955029c85bdcc0a5704990 Mon Sep 17 00:00:00 2001 From: Sayan Nandan Date: Tue, 23 Jul 2024 23:18:41 +0530 Subject: [PATCH] resp: Add RList for decoding lists in responses --- src/query.rs | 8 ++++---- src/response.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/query.rs b/src/query.rs index 99f5fce..787214e 100644 --- a/src/query.rs +++ b/src/query.rs @@ -395,18 +395,18 @@ const LIST_SYM_OPEN: u8 = 0x09; const LIST_SYM_CLOSE: u8 = ']' as u8; /// A list type representing a Skyhash list type, used in parameter lists -pub struct List<'a, T: SQParam> { +pub struct QList<'a, T: SQParam> { l: &'a [T], } -impl<'a, T: SQParam> List<'a, T> { +impl<'a, T: SQParam> QList<'a, T> { /// create a new list pub fn new(l: &'a [T]) -> Self { Self { l } } } -impl<'a, T: SQParam> SQParam for List<'a, T> { +impl<'a, T: SQParam> SQParam for QList<'a, T> { fn append_param(&self, q: &mut Vec) -> usize { q.push(LIST_SYM_OPEN); for param in self.l { @@ -420,7 +420,7 @@ impl<'a, T: SQParam> SQParam for List<'a, T> { #[test] fn list_param() { let data = vec!["hello", "giant", "world"]; - let list = List::new(&data); + let list = QList::new(&data); let q = query!( "insert into apps.social(?, ?, ?)", "username", diff --git a/src/response.rs b/src/response.rs index 1da5f85..b117d34 100644 --- a/src/response.rs +++ b/src/response.rs @@ -405,3 +405,50 @@ impl Deref for Rows { &self.0 } } + +/// A list received from a response +pub struct RList(Vec); + +impl RList { + /// Returns the values of the list + pub fn into_values(self) -> Vec { + self.0 + } +} + +impl Deref for RList { + type Target = [T]; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl FromValue for RList { + fn from_value(v: Value) -> ClientResult { + match v { + Value::List(l) => { + let mut ret = Vec::new(); + for value in l { + ret.push(T::from_value(value)?); + } + Ok(Self(ret)) + } + _ => Err(Error::ParseError(ParseError::TypeMismatch)), + } + } +} + +#[test] +fn resp_list_parse() { + let response_list = Response::Row(Row::new(vec![ + Value::String("sayan".to_owned()), + Value::List(vec![ + Value::String("c".to_owned()), + Value::String("assembly".to_owned()), + Value::String("rust".to_owned()), + ]), + ])); + let (name, languages) = response_list.parse::<(String, RList)>().unwrap(); + assert_eq!(name, "sayan"); + assert_eq!(languages.as_ref(), vec!["c", "assembly", "rust"]); +}