From 1406115111fea7ec682a6cb7e1b16173c2e6f584 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Wed, 4 Oct 2023 03:50:01 +0100 Subject: [PATCH] Introduce TryGetableArray --- sea-orm-macros/src/derives/active_enum.rs | 10 +++++ src/entity/active_enum.rs | 12 ------ src/executor/query.rs | 45 +++++++++++++++++++++++ 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/sea-orm-macros/src/derives/active_enum.rs b/sea-orm-macros/src/derives/active_enum.rs index 591da6f331..db4d5f6e41 100644 --- a/sea-orm-macros/src/derives/active_enum.rs +++ b/sea-orm-macros/src/derives/active_enum.rs @@ -337,6 +337,16 @@ impl ActiveEnum { } } + #[automatically_derived] + impl sea_orm::TryGetableArray for #ident { + fn try_get_by(res: &sea_orm::QueryResult, index: I) -> std::result::Result, sea_orm::TryGetError> { + <::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 for #ident { diff --git a/src/entity/active_enum.rs b/src/entity/active_enum.rs index 5f48f774b0..bb8df73584 100644 --- a/src/entity/active_enum.rs +++ b/src/entity/active_enum.rs @@ -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 TryGetable for Vec -where - T: ActiveEnum, -{ - fn try_get_by(res: &QueryResult, index: I) -> Result { - ::try_get_vec_by(res, index)? - .into_iter() - .map(|value| T::try_from_value(&value).map_err(Into::into)) - .collect() - } -} - impl TryFromU64 for T where T: ActiveEnum, diff --git a/src/executor/query.rs b/src/executor/query.rs index 28093822b9..6e5dfc303c 100644 --- a/src/executor/query.rs +++ b/src/executor/query.rs @@ -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(res: &QueryResult, index: I) -> Result, TryGetError>; +} + +impl TryGetable for Vec +where + T: TryGetableArray, +{ + fn try_get_by(res: &QueryResult, index: I) -> Result { + 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 from an Array of Json + fn from_json_vec(value: serde_json::Value) -> Result, 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")] @@ -1011,6 +1046,16 @@ where } } +#[cfg(feature = "with-json")] +impl TryGetableArray for T +where + T: TryGetableFromJson, +{ + fn try_get_by(res: &QueryResult, index: I) -> Result, 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 {