Rename column name & column enum variant

This commit is contained in:
Billy Chan 2021-09-28 14:27:19 +08:00
parent c12e0cd44e
commit 88776a28ed
No known key found for this signature in database
GPG Key ID: A2D690CAC7DF3CC7
5 changed files with 131 additions and 14 deletions

View File

@ -2,7 +2,7 @@ use crate::util::field_not_ignored;
use heck::CamelCase; use heck::CamelCase;
use proc_macro2::{Ident, TokenStream}; use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote, quote_spanned}; use quote::{format_ident, quote, quote_spanned};
use syn::{Data, DataStruct, Field, Fields, Type}; use syn::{punctuated::Punctuated, token::Comma, Data, DataStruct, Field, Fields, Lit, Meta, Type};
pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<TokenStream> { pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<TokenStream> {
let fields = match data { let fields = match data {
@ -28,7 +28,36 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<Token
let name: Vec<Ident> = fields let name: Vec<Ident> = fields
.clone() .clone()
.into_iter() .into_iter()
.map(|Field { ident, .. }| format_ident!("{}", ident.unwrap().to_string().to_camel_case())) .map(|field| {
let mut ident = format_ident!(
"{}",
field.ident.as_ref().unwrap().to_string().to_camel_case()
);
for attr in field.attrs.iter() {
if let Some(ident) = attr.path.get_ident() {
if ident != "sea_orm" {
continue;
}
} else {
continue;
}
if let Ok(list) = attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)
{
for meta in list.iter() {
if let Meta::NameValue(nv) = meta {
if let Some(name) = nv.path.get_ident() {
if name == "enum_name" {
if let Lit::Str(litstr) = &nv.lit {
ident = syn::parse_str(&litstr.value()).unwrap();
}
}
}
}
}
}
}
ident
})
.collect(); .collect();
let ty: Vec<Type> = fields.into_iter().map(|Field { ty, .. }| ty).collect(); let ty: Vec<Type> = fields.into_iter().map(|Field { ty, .. }| ty).collect();

View File

@ -1,7 +1,7 @@
use heck::{MixedCase, SnakeCase}; use heck::{MixedCase, SnakeCase};
use proc_macro2::{Ident, TokenStream}; use proc_macro2::{Ident, TokenStream};
use quote::{quote, quote_spanned}; use quote::{quote, quote_spanned};
use syn::{Data, DataEnum, Fields, Variant}; use syn::{punctuated::Punctuated, token::Comma, Data, DataEnum, Fields, Lit, Meta, Variant};
pub fn impl_default_as_str(ident: &Ident, data: &Data) -> syn::Result<TokenStream> { pub fn impl_default_as_str(ident: &Ident, data: &Data) -> syn::Result<TokenStream> {
let variants = match data { let variants = match data {
@ -25,8 +25,31 @@ pub fn impl_default_as_str(ident: &Ident, data: &Data) -> syn::Result<TokenStrea
let name: Vec<TokenStream> = variants let name: Vec<TokenStream> = variants
.iter() .iter()
.map(|v| { .map(|v| {
let ident = v.ident.to_string().to_snake_case(); let mut column_name = v.ident.to_string().to_snake_case();
quote! { #ident } for attr in v.attrs.iter() {
if let Some(ident) = attr.path.get_ident() {
if ident != "sea_orm" {
continue;
}
} else {
continue;
}
if let Ok(list) = attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)
{
for meta in list.iter() {
if let Meta::NameValue(nv) = meta {
if let Some(name) = nv.path.get_ident() {
if name == "column_name" {
if let Lit::Str(litstr) = &nv.lit {
column_name = litstr.value();
}
}
}
}
}
}
}
quote! { #column_name }
}) })
.collect(); .collect();

View File

@ -60,9 +60,8 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
if let Fields::Named(fields) = item_struct.fields { if let Fields::Named(fields) = item_struct.fields {
for field in fields.named { for field in fields.named {
if let Some(ident) = &field.ident { if let Some(ident) = &field.ident {
let field_name = let mut field_name =
Ident::new(&ident.to_string().to_case(Case::Pascal), Span::call_site()); Ident::new(&ident.to_string().to_case(Case::Pascal), Span::call_site());
columns_enum.push(quote! { #field_name });
let mut nullable = false; let mut nullable = false;
let mut default_value = None; let mut default_value = None;
@ -71,7 +70,10 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
let mut ignore = false; let mut ignore = false;
let mut unique = false; let mut unique = false;
let mut sql_type = None; let mut sql_type = None;
// search for #[sea_orm(primary_key, auto_increment = false, column_type = "String(Some(255))", default_value = "new user", default_expr = "gen_random_uuid()", nullable, indexed, unique)] let mut column_name = None;
let mut enum_name = None;
let mut is_primary_key = false;
// search for #[sea_orm(primary_key, auto_increment = false, column_type = "String(Some(255))", default_value = "new user", default_expr = "gen_random_uuid()", column_name = "name", enum_name = "Name", nullable, indexed, unique)]
for attr in field.attrs.iter() { for attr in field.attrs.iter() {
if let Some(ident) = attr.path.get_ident() { if let Some(ident) = attr.path.get_ident() {
if ident != "sea_orm" { if ident != "sea_orm" {
@ -116,6 +118,26 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
default_value = Some(nv.lit.to_owned()); default_value = Some(nv.lit.to_owned());
} else if name == "default_expr" { } else if name == "default_expr" {
default_expr = Some(nv.lit.to_owned()); default_expr = Some(nv.lit.to_owned());
} else if name == "column_name" {
if let Lit::Str(litstr) = &nv.lit {
column_name = Some(litstr.value());
} else {
return Err(Error::new(
field.span(),
format!("Invalid column_name {:?}", nv.lit),
));
}
} else if name == "enum_name" {
if let Lit::Str(litstr) = &nv.lit {
let ty: Ident =
syn::parse_str(&litstr.value())?;
enum_name = Some(ty);
} else {
return Err(Error::new(
field.span(),
format!("Invalid enum_name {:?}", nv.lit),
));
}
} }
} }
} }
@ -125,7 +147,7 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
ignore = true; ignore = true;
break; break;
} else if name == "primary_key" { } else if name == "primary_key" {
primary_keys.push(quote! { #field_name }); is_primary_key = true;
primary_key_types.push(field.ty.clone()); primary_key_types.push(field.ty.clone());
} else if name == "nullable" { } else if name == "nullable" {
nullable = true; nullable = true;
@ -142,9 +164,27 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
} }
} }
if let Some(enum_name) = enum_name {
field_name = enum_name;
}
if ignore { if ignore {
columns_enum.pop();
continue; continue;
} else {
let variant_attrs = match &column_name {
Some(column_name) => quote! {
#[sea_orm(column_name = #column_name)]
},
None => quote! {},
};
columns_enum.push(quote! {
#variant_attrs
#field_name
});
}
if is_primary_key {
primary_keys.push(quote! { #field_name });
} }
let field_type = match sql_type { let field_type = match sql_type {

View File

@ -3,7 +3,7 @@ use heck::CamelCase;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote, quote_spanned}; use quote::{format_ident, quote, quote_spanned};
use std::iter::FromIterator; use std::iter::FromIterator;
use syn::Ident; use syn::{punctuated::Punctuated, token::Comma, Ident, Lit, Meta};
enum Error { enum Error {
InputNotStruct, InputNotStruct,
@ -43,10 +43,35 @@ impl DeriveModel {
let column_idents = fields let column_idents = fields
.iter() .iter()
.map(|field| { .map(|field| {
format_ident!( let mut ident = format_ident!(
"{}", "{}",
field.ident.as_ref().unwrap().to_string().to_camel_case() field.ident.as_ref().unwrap().to_string().to_camel_case()
) );
for attr in field.attrs.iter() {
if let Some(ident) = attr.path.get_ident() {
if ident != "sea_orm" {
continue;
}
} else {
continue;
}
if let Ok(list) =
attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)
{
for meta in list.iter() {
if let Meta::NameValue(nv) = meta {
if let Some(name) = nv.path.get_ident() {
if name == "enum_name" {
if let Lit::Str(litstr) = &nv.lit {
ident = syn::parse_str(&litstr.value()).unwrap();
}
}
}
}
}
}
}
ident
}) })
.collect(); .collect();

View File

@ -46,7 +46,7 @@ pub fn derive_primary_key(input: TokenStream) -> TokenStream {
} }
} }
#[proc_macro_derive(DeriveColumn)] #[proc_macro_derive(DeriveColumn, attributes(sea_orm))]
pub fn derive_column(input: TokenStream) -> TokenStream { pub fn derive_column(input: TokenStream) -> TokenStream {
let DeriveInput { ident, data, .. } = parse_macro_input!(input); let DeriveInput { ident, data, .. } = parse_macro_input!(input);