From 0f6a48baa4d8b02ebc8ead1ba80baed1d9b7d55b Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Wed, 4 Oct 2023 21:30:50 +0100 Subject: [PATCH] Rework ActiveEnum: remove the reliance on ValueVec --- src/entity/active_enum.rs | 62 ++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/src/entity/active_enum.rs b/src/entity/active_enum.rs index 6ac81f11..5f48f774 100644 --- a/src/entity/active_enum.rs +++ b/src/entity/active_enum.rs @@ -1,4 +1,4 @@ -use crate::{ColumnDef, DbErr, Iterable, QueryResult, TryFromU64, TryGetError, TryGetable}; +use crate::{ColIdx, ColumnDef, DbErr, Iterable, QueryResult, TryFromU64, TryGetError, TryGetable}; use sea_query::{DynIden, Expr, Nullable, SimpleExpr, Value, ValueType}; /// A Rust representation of enum defined in database. @@ -110,11 +110,11 @@ use sea_query::{DynIden, Expr, Nullable, SimpleExpr, Value, ValueType}; /// impl ActiveModelBehavior for ActiveModel {} /// ``` pub trait ActiveEnum: Sized + Iterable { - /// Define the Rust type that each enum variant represents. - type Value: Into + ValueType + Nullable + TryGetable; + /// Define the Rust type that each enum variant corresponds. + type Value: ActiveEnumValue; - /// Define the enum value in Vector type. - type ValueVec: IntoIterator; + /// This has no purpose. It will be removed in the next major version. + type ValueVec; /// Get the name of enum fn name() -> DynIden; @@ -144,13 +144,59 @@ pub trait ActiveEnum: Sized + Iterable { } } +/// The Rust Value backing ActiveEnums +pub trait ActiveEnumValue: Into + ValueType + Nullable + TryGetable { + /// For getting an array of enum. Postgres only + fn try_get_vec_by(res: &QueryResult, index: I) -> Result, TryGetError>; +} + +macro_rules! impl_active_enum_value { + ($type:ident) => { + impl ActiveEnumValue for $type { + fn try_get_vec_by( + _res: &QueryResult, + _index: I, + ) -> Result, TryGetError> { + panic!("Not supported by `postgres-array`") + } + } + }; +} + +macro_rules! impl_active_enum_value_with_pg_array { + ($type:ident) => { + impl ActiveEnumValue for $type { + fn try_get_vec_by( + _res: &QueryResult, + _index: I, + ) -> Result, TryGetError> { + #[cfg(feature = "postgres-array")] + { + >::try_get_by(_res, _index) + } + #[cfg(not(feature = "postgres-array"))] + panic!("`postgres-array` is not enabled") + } + } + }; +} + +impl_active_enum_value!(u8); +impl_active_enum_value!(u16); +impl_active_enum_value!(u32); +impl_active_enum_value!(u64); +impl_active_enum_value_with_pg_array!(String); +impl_active_enum_value_with_pg_array!(i8); +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, - T::ValueVec: TryGetable, { - fn try_get_by(res: &QueryResult, index: I) -> Result { - ::try_get_by(res, index)? + 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()