Introduce TryGetableArray

This commit is contained in:
Chris Tsang 2023-10-04 03:50:01 +01:00
parent 0f6a48baa4
commit b2cb51380a
3 changed files with 55 additions and 12 deletions

View File

@ -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 {

View File

@ -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,

View File

@ -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
@ -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(json_err)?);
}
Ok(res)
}
_ => Err(TryGetError::DbErr(DbErr::Json(
"Value is not an Array".to_owned(),
))),
}
}
}
#[cfg(feature = "with-json")]
@ -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 {