Skip to content

Commit

Permalink
resp: Add RList for decoding lists in responses
Browse files Browse the repository at this point in the history
  • Loading branch information
ohsayan committed Jul 23, 2024
1 parent 7e50a47 commit 330a8f5
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 4 deletions.
8 changes: 4 additions & 4 deletions src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>) -> usize {
q.push(LIST_SYM_OPEN);
for param in self.l {
Expand All @@ -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",
Expand Down
47 changes: 47 additions & 0 deletions src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,3 +405,50 @@ impl<T: FromRow> Deref for Rows<T> {
&self.0
}
}

/// A list received from a response
pub struct RList<T: FromValue = Value>(Vec<T>);

impl<T: FromValue> RList<T> {
/// Returns the values of the list
pub fn into_values(self) -> Vec<T> {
self.0
}
}

impl<T: FromValue> Deref for RList<T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.0
}
}

impl<T: FromValue> FromValue for RList<T> {
fn from_value(v: Value) -> ClientResult<Self> {
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<String>)>().unwrap();
assert_eq!(name, "sayan");
assert_eq!(languages.as_ref(), vec!["c", "assembly", "rust"]);
}

0 comments on commit 330a8f5

Please sign in to comment.