Skip to content

Commit

Permalink
Add support for deserializing Vec<Vec<T>>
Browse files Browse the repository at this point in the history
diff

comment
  • Loading branch information
0xEdgar committed Mar 4, 2024
1 parent afd8ce5 commit 36e18e6
Showing 1 changed file with 34 additions and 1 deletion.
35 changes: 34 additions & 1 deletion src/types/from_sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,10 @@ impl<'a> FromSql<'a> for uuid::Uuid {
}

macro_rules! from_sql_vec_impl {
( $( $t:ty: $k:pat => $f:expr ),* ) => {
// Base case: Vec<T>
(
$($t:ty: $k:pat => $f:expr),*
) => {
$(
impl<'a> FromSql<'a> for Vec<$t> {
fn from_sql(value: ValueRef<'a>) -> FromSqlResult<Self> {
Expand All @@ -200,6 +203,36 @@ macro_rules! from_sql_vec_impl {
}
}
}
// Recursive case: Vec<Vec<T>>
impl<'a> FromSql<'a> for Vec<Vec<$t>> {
fn from_sql(value: ValueRef<'a>) -> FromSqlResult<Self> {
match value {
ValueRef::Array(SqlType::Array(_), outer_vs) => {
let mut result = Vec::with_capacity(outer_vs.len());
for outer_v in outer_vs.iter() {
match outer_v {
ValueRef::Array($k, inner_vs) => {
let f: fn(ValueRef<'a>) -> FromSqlResult<$t> = $f;
let inner: Vec<$t> = inner_vs.iter().map(|inner_v| f(inner_v.clone())).collect::<std::result::Result<Vec<$t>, _>>()?;
result.push(inner);
}
_ => {
return Err(Error::FromSql(FromSqlError::InvalidType {
src: SqlType::from(outer_v.clone()).to_string(),
dst: format!("Vec<Vec<{}>>", stringify!($t)).into(),
}));
}
}
}
Ok(result)
}
_ => Err(Error::FromSql(FromSqlError::InvalidType {
src: SqlType::from(value.clone()).to_string(),
dst: format!("Vec<Vec<{}>>", stringify!($t)).into(),
})),
}
}
}
)*
};
}
Expand Down

0 comments on commit 36e18e6

Please sign in to comment.