use serde::{Deserialize, Deserializer, Serialize}; use serde_yaml::Value; use sea_orm_codegen::{ DateTimeCrate as CodegenDateTimeCrate, EntityWriterContext, WithPrelude, WithSerde, }; use super::Config; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] pub enum EntityFormat { Expanded, Compact, } #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] #[serde(untagged)] pub enum TableConfig { Specific { specific: Vec }, Exclude { exclude: Vec }, } #[derive(Debug, Clone)] pub enum SerdeEnable { Both, Serialize, Deserialize, None, } #[derive(Debug, Clone)] pub enum Prelude { Enabled, Disabled, AllowUnusedImports, } impl<'de> Deserialize<'de> for SerdeEnable { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { let value = Value::deserialize(deserializer)?; match value { Value::String(s) if s == "serialize" => Ok(SerdeEnable::Serialize), Value::String(s) if s == "deserialize" => Ok(SerdeEnable::Deserialize), Value::Bool(true) => Ok(SerdeEnable::Both), Value::Bool(false) => Ok(SerdeEnable::None), _ => Err(serde::de::Error::custom( "expected 'serialize', 'deserialize', 'true' or 'false'", )), } } } impl Serialize for SerdeEnable { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { match self { SerdeEnable::Both => serializer.serialize_bool(true), SerdeEnable::Serialize => serializer.serialize_str("serialize"), SerdeEnable::Deserialize => serializer.serialize_str("deserialize"), SerdeEnable::None => serializer.serialize_bool(false), } } } impl<'de> Deserialize<'de> for Prelude { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { let value = Value::deserialize(deserializer)?; match value { Value::Bool(true) => Ok(Prelude::Enabled), Value::Bool(false) => Ok(Prelude::Disabled), Value::String(s) if s == "allow_unused_imports" => Ok(Prelude::AllowUnusedImports), _ => Err(serde::de::Error::custom( "expected 'true', 'false', or 'allow_unused_imports'", )), } } } impl Serialize for Prelude { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { match self { Prelude::Enabled => serializer.serialize_bool(true), Prelude::Disabled => serializer.serialize_bool(false), Prelude::AllowUnusedImports => serializer.serialize_str("allow_unused_imports"), } } } #[derive(Deserialize, Serialize, Debug, Clone)] pub struct SeaOrmConfig { pub prelude: Prelude, pub serde: SeaOrmSerdeConfig, pub entity: SeaOrmEntityConfig, } #[derive(Deserialize, Serialize, Debug, Clone)] pub struct SeaOrmSerdeConfig { pub enable: SerdeEnable, pub skip_deserializing_primary_key: bool, pub skip_hidden_column: bool, } #[derive(Deserialize, Serialize, Debug, Clone)] pub struct SeaOrmEntityConfig { pub format: EntityFormat, pub tables: SeaOrmTableConfig, pub extra_derives: SeaOrmExtraDerivesConfig, pub extra_attributes: SeaOrmExtraAttributesConfig, pub date_time_crate: DateTimeCrate, pub with_copy_enums: bool, } #[derive(Deserialize, Serialize, Debug, Clone)] pub struct SeaOrmTableConfig { pub include_hidden: bool, pub skip_seaql_migrations: bool, #[serde(flatten)] pub table_config: Option, } #[derive(Deserialize, Serialize, Debug, Clone)] pub struct SeaOrmExtraDerivesConfig { pub model: Vec, #[serde(rename = "enum")] pub eenum: Vec, } #[derive(Deserialize, Serialize, Debug, Clone)] pub struct SeaOrmExtraAttributesConfig { pub model: Vec, #[serde(rename = "enum")] pub eenum: Vec, } #[derive(Deserialize, Serialize, Debug, Clone)] #[serde(rename_all = "lowercase")] pub enum DateTimeCrate { Time, Chrono, } impl From for CodegenDateTimeCrate { fn from(date_time_crate: DateTimeCrate) -> CodegenDateTimeCrate { match date_time_crate { DateTimeCrate::Chrono => CodegenDateTimeCrate::Chrono, DateTimeCrate::Time => CodegenDateTimeCrate::Time, } } } impl SeaOrmTableConfig { pub fn get_filter(&self) -> Box bool> { let include_hidden = self.include_hidden; if let Some(table) = &self.table_config { match table { TableConfig::Specific { specific } => { let specific = specific.clone(); Box::new(move |table: &String| { (include_hidden || !table.starts_with('_')) && specific.contains(table) }) } TableConfig::Exclude { exclude } => { let exclude = exclude.clone(); Box::new(move |table: &String| { (include_hidden || !table.starts_with('_')) && !exclude.contains(table) }) } } } else if self.skip_seaql_migrations { Box::new(move |table: &String| { (include_hidden || !table.starts_with('_')) && !table.starts_with("seaql_migrations") }) } else { Box::new(move |table: &String| (include_hidden || !table.starts_with('_'))) } } } impl EntityFormat { pub fn is_expanded(&self) -> bool { matches!(self, EntityFormat::Expanded) } } impl From for WithPrelude { fn from(val: Prelude) -> Self { match val { Prelude::Enabled => WithPrelude::All, Prelude::Disabled => WithPrelude::None, Prelude::AllowUnusedImports => WithPrelude::AllAllowUnusedImports, } } } impl From for WithSerde { fn from(val: SerdeEnable) -> Self { match val { SerdeEnable::Both => WithSerde::Both, SerdeEnable::Serialize => WithSerde::Serialize, SerdeEnable::Deserialize => WithSerde::Deserialize, SerdeEnable::None => WithSerde::None, } } } impl From for EntityWriterContext { fn from(val: Config) -> Self { EntityWriterContext::new( val.sea_orm.entity.format.is_expanded(), val.sea_orm.prelude.into(), val.sea_orm.serde.enable.into(), val.sea_orm.entity.with_copy_enums, val.sea_orm.entity.date_time_crate.into(), val.db.database_schema, false, val.sea_orm.serde.skip_deserializing_primary_key, val.sea_orm.serde.skip_hidden_column, val.sea_orm.entity.extra_derives.model, val.sea_orm.entity.extra_attributes.model, val.sea_orm.entity.extra_derives.eenum, val.sea_orm.entity.extra_attributes.eenum, false, false, ) } }