diff --git a/Cargo.toml b/Cargo.toml index c477626d..6e929ce5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ ".", + "sea-orm-macros", "examples/sqlx-mysql", ] @@ -25,6 +26,7 @@ path = "src/lib.rs" async-trait = "^0.1" futures = { version = "^0.3" } sea-query = { path = "../sea-query", version = "^0.10", features = [ "sqlx-mysql" ] } +sea-orm-macros = { path = "sea-orm-macros", optional = true } # sea-schema = { path = "../sea-schema" } serde = { version = "^1.0", features = [ "derive" ] } sqlx = { version = "^0.5", optional = true } @@ -32,7 +34,7 @@ strum = { version = "^0.20", features = [ "derive" ] } [features] debug-print = [] -default = [ "sqlx-mysql", "runtime-async-std-native-tls" ] +default = [ "macros", "sqlx-mysql", "runtime-async-std-native-tls" ] sqlx-dep = [ "sqlx" ] sqlx-mysql = [ "sqlx-dep", "sea-query/sqlx-mysql", "sqlx/mysql" ] sqlx-postgres = [ "sqlx-dep", "sea-query/sqlx-postgres", "sqlx/postgres" ] @@ -42,3 +44,4 @@ runtime-tokio-native-tls = [ "sqlx/runtime-tokio-native-tls" ] runtime-actix-rustls = [ "sqlx/runtime-actix-rustls" ] runtime-async-std-rustls = [ "sqlx/runtime-async-std-rustls" ] runtime-tokio-rustls = [ "sqlx/runtime-tokio-rustls" ] +macros = [ "sea-orm-macros" ] diff --git a/examples/sqlx-mysql/src/example_cake.rs b/examples/sqlx-mysql/src/example_cake.rs index ad893a56..f987136e 100644 --- a/examples/sqlx-mysql/src/example_cake.rs +++ b/examples/sqlx-mysql/src/example_cake.rs @@ -1,21 +1,22 @@ use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, DeriveEntity)] +#[entity = "cake"] pub struct Entity; -#[derive(Clone, Debug, Default, PartialEq)] +#[derive(Clone, Debug, Default, PartialEq, DeriveModel)] pub struct Model { pub id: i32, pub name: String, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] pub enum Column { Id, Name, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] pub enum PrimaryKey { Id, } @@ -25,16 +26,6 @@ pub enum Relation { Fruit, } -impl EntityTrait for Entity { - type Model = Model; - - type Column = Column; - - type PrimaryKey = PrimaryKey; - - type Relation = Relation; -} - impl ColumnTrait for Column { type EntityName = Entity; @@ -68,91 +59,3 @@ impl Model { Entity::find_related().belongs_to::(self) } } - -// TODO: implement with derive macro -impl EntityName for Entity {} - -// TODO: implement with derive macro -impl IdenStatic for Entity { - fn as_str(&self) -> &str { - "cake" - } -} - -// TODO: implement with derive macro -impl Iden for Entity { - fn unquoted(&self, s: &mut dyn std::fmt::Write) { - write!(s, "{}", self.as_str()).unwrap(); - } -} - -// TODO: implement with derive macro -impl ModelTrait for Model { - type Column = Column; - - fn get(&self, c: Self::Column) -> Value { - match c { - Column::Id => self.id.clone().into(), - Column::Name => self.name.clone().into(), - } - } - - fn set(&mut self, c: Self::Column, v: Value) { - match c { - Column::Id => self.id = v.unwrap(), - Column::Name => self.name = v.unwrap(), - } - } - - fn from_query_result(row: &QueryResult, pre: &str) -> Result { - Ok(Self { - id: row.try_get(pre, Column::Id.as_str())?, - name: row.try_get(pre, Column::Name.as_str())?, - }) - } -} - -// TODO: implement with derive macro -impl Iden for Column { - fn unquoted(&self, s: &mut dyn std::fmt::Write) { - write!(s, "{}", self.as_str()).unwrap(); - } -} - -// TODO: implement with derive macro -impl IdenStatic for Column { - fn as_str(&self) -> &str { - match self { - Self::Id => "id", - Self::Name => "name", - } - } -} - -// TODO: implement with derive macro -impl Iden for PrimaryKey { - fn unquoted(&self, s: &mut dyn std::fmt::Write) { - write!(s, "{}", self.as_str()).unwrap(); - } -} - -// TODO: implement with derive macro -impl IdenStatic for PrimaryKey { - fn as_str(&self) -> &str { - match self { - Self::Id => "id", - } - } -} - -// TODO: implement with derive macro -impl PrimaryKeyTrait for PrimaryKey {} - -// TODO: implement with derive macro -impl PrimaryKeyOfModel for PrimaryKey { - fn into_column(self) -> ::Column { - match self { - Self::Id => Column::Id, - } - } -} diff --git a/examples/sqlx-mysql/src/example_fruit.rs b/examples/sqlx-mysql/src/example_fruit.rs index 077616e3..b393e3d6 100644 --- a/examples/sqlx-mysql/src/example_fruit.rs +++ b/examples/sqlx-mysql/src/example_fruit.rs @@ -1,23 +1,24 @@ use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, DeriveEntity)] +#[entity = "fruit"] pub struct Entity; -#[derive(Clone, Debug, Default, PartialEq)] +#[derive(Clone, Debug, Default, PartialEq, DeriveModel)] pub struct Model { pub id: i32, pub name: String, pub cake_id: Option, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] pub enum Column { Id, Name, CakeId, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] pub enum PrimaryKey { Id, } @@ -25,16 +26,6 @@ pub enum PrimaryKey { #[derive(Copy, Clone, Debug, EnumIter)] pub enum Relation {} -impl EntityTrait for Entity { - type Model = Model; - - type Column = Column; - - type PrimaryKey = PrimaryKey; - - type Relation = Relation; -} - impl ColumnTrait for Column { type EntityName = Entity; @@ -52,95 +43,3 @@ impl RelationTrait for Relation { panic!() } } - -// TODO: implement with derive macro -impl EntityName for Entity {} - -// TODO: implement with derive macro -impl IdenStatic for Entity { - fn as_str(&self) -> &str { - "fruit" - } -} - -// TODO: implement with derive macro -impl Iden for Entity { - fn unquoted(&self, s: &mut dyn std::fmt::Write) { - write!(s, "{}", self.as_str()).unwrap(); - } -} - -// TODO: implement with derive macro -impl ModelTrait for Model { - type Column = Column; - - fn get(&self, c: Self::Column) -> Value { - match c { - Column::Id => self.id.clone().into(), - Column::Name => self.name.clone().into(), - Column::CakeId => self.cake_id.clone().into(), - } - } - - fn set(&mut self, c: Self::Column, v: Value) { - match c { - Column::Id => self.id = v.unwrap(), - Column::Name => self.name = v.unwrap(), - Column::CakeId => self.cake_id = v.unwrap(), - } - } - - fn from_query_result(row: &QueryResult, pre: &str) -> Result { - Ok(Self { - id: row.try_get(pre, Column::Id.as_str())?, - name: row.try_get(pre, Column::Name.as_str())?, - cake_id: row.try_get(pre, Column::CakeId.as_str())?, - }) - } -} - -// TODO: implement with derive macro -impl Iden for Column { - fn unquoted(&self, s: &mut dyn std::fmt::Write) { - write!(s, "{}", self.as_str()).unwrap(); - } -} - -// TODO: implement with derive macro -impl IdenStatic for Column { - fn as_str(&self) -> &str { - match self { - Self::Id => "id", - Self::Name => "name", - Self::CakeId => "cake_id", - } - } -} - -// TODO: implement with derive macro -impl Iden for PrimaryKey { - fn unquoted(&self, s: &mut dyn std::fmt::Write) { - write!(s, "{}", self.as_str()).unwrap(); - } -} - -// TODO: implement with derive macro -impl IdenStatic for PrimaryKey { - fn as_str(&self) -> &str { - match self { - Self::Id => "id", - } - } -} - -// TODO: implement with derive macro -impl PrimaryKeyTrait for PrimaryKey {} - -// TODO: implement with derive macro -impl PrimaryKeyOfModel for PrimaryKey { - fn into_column(self) -> ::Column { - match self { - Self::Id => Column::Id, - } - } -} diff --git a/sea-orm-macros/Cargo.toml b/sea-orm-macros/Cargo.toml new file mode 100644 index 00000000..9d8854a0 --- /dev/null +++ b/sea-orm-macros/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "sea-orm-macros" +version = "0.1.0" +authors = [ "Billy Chan " ] +edition = "2018" +description = "" +license = "MIT OR Apache-2.0" +documentation = "https://docs.rs/sea-orm" +repository = "https://github.com/SeaQL/sea-orm" +categories = [ "database" ] +keywords = [ "orm", "database", "sql", "mysql", "postgres", "sqlite" ] +publish = false + +[lib] +name = "sea_orm_macros" +path = "src/lib.rs" +proc-macro = true + +[dependencies] +syn = { version = "1", default-features = false, features = [ "derive", "parsing", "proc-macro", "printing" ] } +quote = "1" +heck = "0.3" +proc-macro2 = "1" diff --git a/sea-orm-macros/src/derives/column.rs b/sea-orm-macros/src/derives/column.rs new file mode 100644 index 00000000..4e385a32 --- /dev/null +++ b/sea-orm-macros/src/derives/column.rs @@ -0,0 +1,48 @@ +use heck::SnakeCase; +use proc_macro2::{Ident, TokenStream}; +use syn::{Data, DataEnum, Fields, Variant}; +use quote::{quote, quote_spanned}; + +pub fn expend_derive_column(ident: Ident, data: Data) -> syn::Result { + let variants = match data { + syn::Data::Enum(DataEnum { variants, .. }) => variants, + _ => return Ok(quote_spanned! { + ident.span() => compile_error!("you can only derive DeriveColumn on enums"); + }), + }; + + let variant: Vec = variants + .iter() + .map(|Variant { ident, fields, .. }| { + match fields { + Fields::Named(_) => quote! { #ident{..} }, + Fields::Unnamed(_) => quote! { #ident(..) }, + Fields::Unit => quote! { #ident }, + } + }) + .collect(); + + let name: Vec = variants + .iter() + .map(|v| { + let ident = v.ident.to_string().to_snake_case(); + quote! { #ident } + }) + .collect(); + + Ok(quote!( + impl Iden for #ident { + fn unquoted(&self, s: &mut dyn std::fmt::Write) { + write!(s, "{}", self.as_str()).unwrap(); + } + } + + impl IdenStatic for #ident { + fn as_str(&self) -> &str { + match self { + #(Self::#variant => #name),* + } + } + } + )) +} \ No newline at end of file diff --git a/sea-orm-macros/src/derives/entity.rs b/sea-orm-macros/src/derives/entity.rs new file mode 100644 index 00000000..373a95f5 --- /dev/null +++ b/sea-orm-macros/src/derives/entity.rs @@ -0,0 +1,53 @@ +use heck::SnakeCase; +use proc_macro2::{Ident, TokenStream}; +use syn::{Attribute, Meta}; +use quote::quote; + +fn get_entity_attr(attrs: &[Attribute]) -> Option { + for attr in attrs { + let name_value = match attr.parse_meta() { + Ok(Meta::NameValue(nv)) => nv, + _ => continue, + }; + if name_value.path.is_ident("entity") { + return Some(name_value.lit); + } + } + None +} + +pub fn expend_derive_entity(ident: Ident, attrs: Vec) -> syn::Result { + let entity_name = match get_entity_attr(&attrs) { + Some(lit) => quote! { #lit }, + None => { + let normalized = ident.to_string().to_snake_case(); + quote! { #normalized } + } + }; + + Ok(quote!( + impl EntityName for #ident {} + + impl IdenStatic for #ident { + fn as_str(&self) -> &str { + #entity_name + } + } + + impl Iden for #ident { + fn unquoted(&self, s: &mut dyn std::fmt::Write) { + write!(s, "{}", self.as_str()).unwrap(); + } + } + + impl EntityTrait for #ident { + type Model = Model; + + type Column = Column; + + type PrimaryKey = PrimaryKey; + + type Relation = Relation; + } + )) +} \ No newline at end of file diff --git a/sea-orm-macros/src/derives/mod.rs b/sea-orm-macros/src/derives/mod.rs new file mode 100644 index 00000000..e6139bcc --- /dev/null +++ b/sea-orm-macros/src/derives/mod.rs @@ -0,0 +1,9 @@ +mod entity; +mod primary_key; +mod column; +mod model; + +pub use entity::*; +pub use primary_key::*; +pub use column::*; +pub use model::*; \ No newline at end of file diff --git a/sea-orm-macros/src/derives/model.rs b/sea-orm-macros/src/derives/model.rs new file mode 100644 index 00000000..375e1d82 --- /dev/null +++ b/sea-orm-macros/src/derives/model.rs @@ -0,0 +1,57 @@ +use heck::CamelCase; +use proc_macro2::{Ident, TokenStream}; +use syn::{Data, DataStruct, Field, Fields}; +use quote::{format_ident, quote, quote_spanned}; + +pub fn expend_derive_model(ident: Ident, data: Data) -> syn::Result { + let fields = match data { + Data::Struct(DataStruct { + fields: Fields::Named(named), + .. + }) => { + named.named + }, + _ => return Ok(quote_spanned! { + ident.span() => compile_error!("you can only derive DeriveModel on structs"); + }), + }; + + let field: Vec = fields + .clone() + .into_iter() + .map(|Field { ident, .. }| { + format_ident!("{}", ident.unwrap().to_string()) + }) + .collect(); + + let name: Vec = fields + .into_iter() + .map(|Field { ident, .. }| { + format_ident!("{}", ident.unwrap().to_string().to_camel_case()) + }) + .collect(); + + Ok(quote!( + impl ModelTrait for #ident { + type Column = Column; + + fn get(&self, c: Self::Column) -> Value { + match c { + #(Self::Column::#name => self.#field.clone().into()),* + } + } + + fn set(&mut self, c: Self::Column, v: Value) { + match c { + #(Self::Column::#name => self.#field = v.unwrap()),* + } + } + + fn from_query_result(row: &QueryResult, pre: &str) -> Result { + Ok(Self { + #(#field: row.try_get(pre, Self::Column::#name.as_str().into())?),* + }) + } + } + )) +} \ No newline at end of file diff --git a/sea-orm-macros/src/derives/primary_key.rs b/sea-orm-macros/src/derives/primary_key.rs new file mode 100644 index 00000000..bde0505a --- /dev/null +++ b/sea-orm-macros/src/derives/primary_key.rs @@ -0,0 +1,58 @@ +use heck::SnakeCase; +use proc_macro2::{Ident, TokenStream}; +use syn::{Data, DataEnum, Fields, Variant}; +use quote::{quote, quote_spanned}; + +pub fn expend_derive_primary_key(ident: Ident, data: Data) -> syn::Result { + let variants = match data { + syn::Data::Enum(DataEnum { variants, .. }) => variants, + _ => return Ok(quote_spanned! { + ident.span() => compile_error!("you can only derive DerivePrimaryKey on enums"); + }), + }; + + let variant: Vec = variants + .iter() + .map(|Variant { ident, fields, .. }| { + match fields { + Fields::Named(_) => quote! { #ident{..} }, + Fields::Unnamed(_) => quote! { #ident(..) }, + Fields::Unit => quote! { #ident }, + } + }) + .collect(); + + let name: Vec = variants + .iter() + .map(|v| { + let ident = v.ident.to_string().to_snake_case(); + quote! { #ident } + }) + .collect(); + + Ok(quote!( + impl Iden for #ident { + fn unquoted(&self, s: &mut dyn std::fmt::Write) { + write!(s, "{}", self.as_str()).unwrap(); + } + } + + impl IdenStatic for #ident { + fn as_str(&self) -> &str { + match self { + #(Self::#variant => #name),* + } + } + } + + impl PrimaryKeyTrait for #ident {} + + impl PrimaryKeyOfModel for #ident { + fn into_column(self) -> ::Column { + match self { + #(Self::#variant => Column::#variant),* + } + } + } + )) +} \ No newline at end of file diff --git a/sea-orm-macros/src/lib.rs b/sea-orm-macros/src/lib.rs new file mode 100644 index 00000000..07aa7cc6 --- /dev/null +++ b/sea-orm-macros/src/lib.rs @@ -0,0 +1,54 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; +use syn::{DeriveInput, parse_macro_input}; + +mod derives; + +#[proc_macro_derive(DeriveEntity, attributes(entity))] +pub fn derive_entity(input: TokenStream) -> TokenStream { + let DeriveInput { + ident, attrs, .. + } = parse_macro_input!(input); + + match derives::expend_derive_entity(ident, attrs) { + Ok(ts) => ts.into(), + Err(e) => e.to_compile_error().into(), + } +} + +#[proc_macro_derive(DerivePrimaryKey)] +pub fn derive_primary_key(input: TokenStream) -> TokenStream { + let DeriveInput { + ident, data, .. + } = parse_macro_input!(input); + + match derives::expend_derive_primary_key(ident, data) { + Ok(ts) => ts.into(), + Err(e) => e.to_compile_error().into(), + } +} + +#[proc_macro_derive(DeriveColumn)] +pub fn derive_column(input: TokenStream) -> TokenStream { + let DeriveInput { + ident, data, .. + } = parse_macro_input!(input); + + match derives::expend_derive_column(ident, data) { + Ok(ts) => ts.into(), + Err(e) => e.to_compile_error().into(), + } +} + +#[proc_macro_derive(DeriveModel)] +pub fn derive_model(input: TokenStream) -> TokenStream { + let DeriveInput { + ident, data, .. + } = parse_macro_input!(input); + + match derives::expend_derive_model(ident, data) { + Ok(ts) => ts.into(), + Err(e) => e.to_compile_error().into(), + } +} \ No newline at end of file diff --git a/src/entity/prelude.rs b/src/entity/prelude.rs index a02650c9..878314cb 100644 --- a/src/entity/prelude.rs +++ b/src/entity/prelude.rs @@ -1,5 +1,5 @@ pub use crate::{ ColumnTrait, ColumnType, EntityName, EntityTrait, EnumIter, Iden, IdenStatic, ModelTrait, PrimaryKeyOfModel, PrimaryKeyTrait, QueryResult, Related, RelationDef, RelationTrait, Select, - TypeErr, Value, + TypeErr, Value, DeriveEntity, DerivePrimaryKey, DeriveColumn, DeriveModel, }; diff --git a/src/lib.rs b/src/lib.rs index 295ad3c8..7b3a9b8c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,3 +15,9 @@ pub use query::*; pub use sea_query; pub use sea_query::Iden; pub use strum::EnumIter; +pub use sea_orm_macros::{ + DeriveEntity, + DerivePrimaryKey, + DeriveColumn, + DeriveModel, +}; diff --git a/src/tests_cfg/cake.rs b/src/tests_cfg/cake.rs index 74c127fd..0221a672 100644 --- a/src/tests_cfg/cake.rs +++ b/src/tests_cfg/cake.rs @@ -1,21 +1,22 @@ use crate::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, DeriveEntity)] +#[entity = "cake"] pub struct Entity; -#[derive(Clone, Debug, Default, PartialEq)] +#[derive(Clone, Debug, Default, PartialEq, DeriveModel)] pub struct Model { pub id: i32, pub name: String, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] pub enum Column { Id, Name, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] pub enum PrimaryKey { Id, } @@ -25,16 +26,6 @@ pub enum Relation { Fruit, } -impl EntityTrait for Entity { - type Model = Model; - - type Column = Column; - - type PrimaryKey = PrimaryKey; - - type Relation = Relation; -} - impl ColumnTrait for Column { type EntityName = Entity; @@ -68,91 +59,3 @@ impl Model { Entity::find_related().belongs_to::(self) } } - -// TODO: implement with derive macro -impl EntityName for Entity {} - -// TODO: implement with derive macro -impl IdenStatic for Entity { - fn as_str(&self) -> &str { - "cake" - } -} - -// TODO: implement with derive macro -impl Iden for Entity { - fn unquoted(&self, s: &mut dyn std::fmt::Write) { - write!(s, "{}", self.as_str()).unwrap(); - } -} - -// TODO: implement with derive macro -impl ModelTrait for Model { - type Column = Column; - - fn get(&self, c: Self::Column) -> Value { - match c { - Column::Id => self.id.clone().into(), - Column::Name => self.name.clone().into(), - } - } - - fn set(&mut self, c: Self::Column, v: Value) { - match c { - Column::Id => self.id = v.unwrap(), - Column::Name => self.name = v.unwrap(), - } - } - - fn from_query_result(row: &QueryResult, pre: &str) -> Result { - Ok(Self { - id: row.try_get(pre, Column::Id.as_str())?, - name: row.try_get(pre, Column::Name.as_str())?, - }) - } -} - -// TODO: implement with derive macro -impl Iden for Column { - fn unquoted(&self, s: &mut dyn std::fmt::Write) { - write!(s, "{}", self.as_str()).unwrap(); - } -} - -// TODO: implement with derive macro -impl IdenStatic for Column { - fn as_str(&self) -> &str { - match self { - Self::Id => "id", - Self::Name => "name", - } - } -} - -// TODO: implement with derive macro -impl Iden for PrimaryKey { - fn unquoted(&self, s: &mut dyn std::fmt::Write) { - write!(s, "{}", self.as_str()).unwrap(); - } -} - -// TODO: implement with derive macro -impl IdenStatic for PrimaryKey { - fn as_str(&self) -> &str { - match self { - Self::Id => "id", - } - } -} - -// TODO: implement with derive macro -impl PrimaryKeyTrait for PrimaryKey {} - -// TODO: implement with derive macro -impl PrimaryKeyOfModel for PrimaryKey { - fn into_column(self) -> ::Column { - match self { - Self::Id => Column::Id, - } - } -} diff --git a/src/tests_cfg/fruit.rs b/src/tests_cfg/fruit.rs index e32e05b0..fa44183c 100644 --- a/src/tests_cfg/fruit.rs +++ b/src/tests_cfg/fruit.rs @@ -1,23 +1,24 @@ use crate::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, DeriveEntity)] +#[entity = "fruit"] pub struct Entity; -#[derive(Clone, Debug, Default, PartialEq)] +#[derive(Clone, Debug, Default, PartialEq, DeriveModel)] pub struct Model { pub id: i32, pub name: String, pub cake_id: Option, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] pub enum Column { Id, Name, CakeId, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] pub enum PrimaryKey { Id, } @@ -25,16 +26,6 @@ pub enum PrimaryKey { #[derive(Copy, Clone, Debug, EnumIter)] pub enum Relation {} -impl EntityTrait for Entity { - type Model = Model; - - type Column = Column; - - type PrimaryKey = PrimaryKey; - - type Relation = Relation; -} - impl ColumnTrait for Column { type EntityName = Entity; @@ -52,95 +43,3 @@ impl RelationTrait for Relation { panic!() } } - -// TODO: implement with derive macro -impl EntityName for Entity {} - -// TODO: implement with derive macro -impl IdenStatic for Entity { - fn as_str(&self) -> &str { - "fruit" - } -} - -// TODO: implement with derive macro -impl Iden for Entity { - fn unquoted(&self, s: &mut dyn std::fmt::Write) { - write!(s, "{}", self.as_str()).unwrap(); - } -} - -// TODO: implement with derive macro -impl ModelTrait for Model { - type Column = Column; - - fn get(&self, c: Self::Column) -> Value { - match c { - Column::Id => self.id.clone().into(), - Column::Name => self.name.clone().into(), - Column::CakeId => self.cake_id.clone().into(), - } - } - - fn set(&mut self, c: Self::Column, v: Value) { - match c { - Column::Id => self.id = v.unwrap(), - Column::Name => self.name = v.unwrap(), - Column::CakeId => self.cake_id = v.unwrap(), - } - } - - fn from_query_result(row: &QueryResult, pre: &str) -> Result { - Ok(Self { - id: row.try_get(pre, Column::Id.as_str())?, - name: row.try_get(pre, Column::Name.as_str())?, - cake_id: row.try_get(pre, Column::CakeId.as_str())?, - }) - } -} - -// TODO: implement with derive macro -impl Iden for Column { - fn unquoted(&self, s: &mut dyn std::fmt::Write) { - write!(s, "{}", self.as_str()).unwrap(); - } -} - -// TODO: implement with derive macro -impl IdenStatic for Column { - fn as_str(&self) -> &str { - match self { - Self::Id => "id", - Self::Name => "name", - Self::CakeId => "cake_id", - } - } -} - -// TODO: implement with derive macro -impl Iden for PrimaryKey { - fn unquoted(&self, s: &mut dyn std::fmt::Write) { - write!(s, "{}", self.as_str()).unwrap(); - } -} - -// TODO: implement with derive macro -impl IdenStatic for PrimaryKey { - fn as_str(&self) -> &str { - match self { - Self::Id => "id", - } - } -} - -// TODO: implement with derive macro -impl PrimaryKeyTrait for PrimaryKey {} - -// TODO: implement with derive macro -impl PrimaryKeyOfModel for PrimaryKey { - fn into_column(self) -> ::Column { - match self { - Self::Id => Column::Id, - } - } -}