Skip to content

Commit

Permalink
Introduce TryGetableArray
Browse files Browse the repository at this point in the history
  • Loading branch information
tyt2y3 committed Oct 4, 2023
1 parent 0f6a48b commit 1406115
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 12 deletions.
10 changes: 10 additions & 0 deletions sea-orm-macros/src/derives/active_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,16 @@ impl ActiveEnum {
}
}

#[automatically_derived]
impl sea_orm::TryGetableArray for #ident {
fn try_get_by<I: sea_orm::ColIdx>(res: &sea_orm::QueryResult, index: I) -> std::result::Result<Vec<Self>, sea_orm::TryGetError> {
<<Self as sea_orm::ActiveEnum>::Value as sea_orm::ActiveEnumValue>::try_get_vec_by(res, index)?
.into_iter()
.map(|value| Self::try_from_value(&value).map_err(Into::into))
.collect()
}
}

#[automatically_derived]
#[allow(clippy::from_over_into)]
impl Into<sea_orm::sea_query::Value> for #ident {
Expand Down
12 changes: 0 additions & 12 deletions src/entity/active_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,18 +191,6 @@ impl_active_enum_value_with_pg_array!(i16);
impl_active_enum_value_with_pg_array!(i32);
impl_active_enum_value_with_pg_array!(i64);

impl<T> TryGetable for Vec<T>
where
T: ActiveEnum,
{
fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError> {
<T::Value>::try_get_vec_by(res, index)?
.into_iter()
.map(|value| T::try_from_value(&value).map_err(Into::into))
.collect()
}
}

impl<T> TryFromU64 for T
where
T: ActiveEnum,
Expand Down
45 changes: 45 additions & 0 deletions src/executor/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,25 @@ fn try_get_many_with_slice_len_of(len: usize, cols: &[String]) -> Result<(), Try
}
}

/// An interface to get an array of values from the query result.
/// A type can only implement `ActiveEnum` or `TryGetableFromJson`, but not both.
/// A blanket impl is provided for `TryGetableFromJson`, while the impl for `ActiveEnum`
/// is provided by the `DeriveActiveEnum` macro. So as an end user you won't normally
/// touch this trait.
pub trait TryGetableArray: Sized {
/// Just a delegate
fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Vec<Self>, TryGetError>;
}

impl<T> TryGetable for Vec<T>
where
T: TryGetableArray,
{
fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError> {
T::try_get_by(res, index)
}
}

// TryGetableFromJson //

/// An interface to get a JSON from the query result
Expand Down Expand Up @@ -999,6 +1018,22 @@ where
_ => unreachable!(),
}
}

/// Get a Vec<Self> from an Array of Json
fn from_json_vec(value: serde_json::Value) -> Result<Vec<Self>, TryGetError> {
match value {
serde_json::Value::Array(values) => {
let mut res = Vec::new();
for item in values {
res.push(serde_json::from_value(item).map_err(|e| json_err(e))?);
}
Ok(res)
}
_ => Err(TryGetError::DbErr(DbErr::Json(
"Value is not an Array".to_owned(),
))),
}
}
}

#[cfg(feature = "with-json")]
Expand All @@ -1011,6 +1046,16 @@ where
}
}

#[cfg(feature = "with-json")]
impl<T> TryGetableArray for T
where
T: TryGetableFromJson,
{
fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Vec<T>, TryGetError> {
T::from_json_vec(serde_json::Value::try_get_by(res, index)?)
}
}

// TryFromU64 //
/// Try to convert a type to a u64
pub trait TryFromU64: Sized {
Expand Down

0 comments on commit 1406115

Please sign in to comment.