Upgrading to syn v2 (#1713)
* resetted and re-did the changes * fmt * upgraded to syn2 for sea-orm-codegen * Rename `bae2` * Drop the use of `#[sea_orm(table_name = "col_name")]` in `DeriveColumn` * unified derived input metadata parsing filter * Propagate errors --------- Co-authored-by: Billy Chan <ccw.billy.123@gmail.com>
This commit is contained in:
parent
35c274818b
commit
64342b105c
@ -18,7 +18,7 @@ path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
sea-query = { version = "0.29.0-rc.2", default-features = false, features = ["thread-safe"] }
|
||||
syn = { version = "1", default-features = false, features = ["parsing", "proc-macro", "derive", "printing"] }
|
||||
syn = { version = "2", default-features = false, features = ["parsing", "proc-macro", "derive", "printing"] }
|
||||
quote = { version = "1", default-features = false }
|
||||
heck = { version = "0.4", default-features = false }
|
||||
proc-macro2 = { version = "1", default-features = false }
|
||||
|
@ -18,8 +18,8 @@ path = "src/lib.rs"
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
bae = { version = "0.1", default-features = false, optional = true }
|
||||
syn = { version = "1", default-features = false, features = ["parsing", "proc-macro", "derive", "printing"] }
|
||||
bae = { version = "1", package = "bae2", default-features = false, optional = true }
|
||||
syn = { version = "2", default-features = false, features = ["parsing", "proc-macro", "derive", "printing"] }
|
||||
quote = { version = "1", default-features = false }
|
||||
heck = { version = "0.4", default-features = false }
|
||||
proc-macro2 = { version = "1", default-features = false }
|
||||
|
@ -2,7 +2,7 @@ use super::util::camel_case_with_escaped_non_uax31;
|
||||
use heck::ToUpperCamelCase;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote, quote_spanned};
|
||||
use syn::{parse, punctuated::Punctuated, token::Comma, Expr, Lit, LitInt, LitStr, Meta, UnOp};
|
||||
use syn::{parse, Expr, Lit, LitInt, LitStr, UnOp};
|
||||
|
||||
enum Error {
|
||||
InputNotEnum,
|
||||
@ -37,25 +37,19 @@ impl ActiveEnum {
|
||||
let mut db_type = Err(Error::TT(quote_spanned! {
|
||||
ident_span => compile_error!("Missing macro attribute `db_type`");
|
||||
}));
|
||||
for attr in input.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 == "rs_type" {
|
||||
if let Lit::Str(litstr) = &nv.lit {
|
||||
rs_type = syn::parse_str::<TokenStream>(&litstr.value())
|
||||
.map_err(Error::Syn);
|
||||
}
|
||||
} else if name == "db_type" {
|
||||
if let Lit::Str(litstr) = &nv.lit {
|
||||
|
||||
input
|
||||
.attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.path().is_ident("sea_orm"))
|
||||
.try_for_each(|attr| {
|
||||
attr.parse_nested_meta(|meta| {
|
||||
if meta.path.is_ident("rs_type") {
|
||||
let litstr: LitStr = meta.value()?.parse()?;
|
||||
rs_type =
|
||||
syn::parse_str::<TokenStream>(&litstr.value()).map_err(Error::Syn);
|
||||
} else if meta.path.is_ident("db_type") {
|
||||
let litstr: LitStr = meta.value()?.parse()?;
|
||||
let s = litstr.value();
|
||||
match s.as_ref() {
|
||||
"Enum" => {
|
||||
@ -67,21 +61,22 @@ impl ActiveEnum {
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
db_type = syn::parse_str::<TokenStream>(&s)
|
||||
.map_err(Error::Syn);
|
||||
db_type = syn::parse_str::<TokenStream>(&s).map_err(Error::Syn);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if name == "enum_name" {
|
||||
if let Lit::Str(litstr) = &nv.lit {
|
||||
} else if meta.path.is_ident("enum_name") {
|
||||
let litstr: LitStr = meta.value()?.parse()?;
|
||||
enum_name = litstr.value();
|
||||
} else {
|
||||
return Err(meta.error(format!(
|
||||
"Unknown attribute parameter found: {:?}",
|
||||
meta.path.get_ident()
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.map_err(Error::Syn)
|
||||
})?;
|
||||
|
||||
let variant_vec = match input.data {
|
||||
syn::Data::Enum(syn::DataEnum { variants, .. }) => variants,
|
||||
@ -96,33 +91,26 @@ impl ActiveEnum {
|
||||
let mut string_value = None;
|
||||
let mut num_value = None;
|
||||
for attr in variant.attrs.iter() {
|
||||
if let Some(ident) = attr.path.get_ident() {
|
||||
if ident != "sea_orm" {
|
||||
if !attr.path().is_ident("sea_orm") {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
if let Ok(list) = attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)
|
||||
{
|
||||
for meta in list {
|
||||
if let Meta::NameValue(nv) = meta {
|
||||
if let Some(name) = nv.path.get_ident() {
|
||||
if name == "string_value" {
|
||||
if let Lit::Str(lit) = nv.lit {
|
||||
attr.parse_nested_meta(|meta| {
|
||||
if meta.path.is_ident("string_value") {
|
||||
is_string = true;
|
||||
string_value = Some(lit);
|
||||
}
|
||||
} else if name == "num_value" {
|
||||
if let Lit::Int(lit) = nv.lit {
|
||||
string_value = Some(meta.value()?.parse::<LitStr>()?);
|
||||
} else if meta.path.is_ident("num_value") {
|
||||
is_int = true;
|
||||
num_value = Some(lit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
num_value = Some(meta.value()?.parse::<LitInt>()?);
|
||||
} else {
|
||||
return Err(meta.error(format!(
|
||||
"Unknown attribute parameter found: {:?}",
|
||||
meta.path.get_ident()
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.map_err(Error::Syn)?;
|
||||
}
|
||||
|
||||
if is_string && is_int {
|
||||
|
@ -4,11 +4,7 @@ use super::util::{
|
||||
use heck::ToUpperCamelCase;
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{format_ident, quote, quote_spanned};
|
||||
use syn::{
|
||||
punctuated::{IntoIter, Punctuated},
|
||||
token::Comma,
|
||||
Data, DataStruct, Field, Fields, Lit, Meta, Type,
|
||||
};
|
||||
use syn::{punctuated::IntoIter, Data, DataStruct, Expr, Field, Fields, LitStr, Type};
|
||||
|
||||
/// Method to derive an [ActiveModel](sea_orm::ActiveModel)
|
||||
pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<TokenStream> {
|
||||
@ -47,32 +43,28 @@ fn derive_active_model(all_fields: IntoIter<Field>) -> syn::Result<TokenStream>
|
||||
let ident = trim_starting_raw_identifier(ident).to_upper_camel_case();
|
||||
let ident = escape_rust_keyword(ident);
|
||||
let mut ident = format_ident!("{}", &ident);
|
||||
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 {
|
||||
field
|
||||
.attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.path().is_ident("sea_orm"))
|
||||
.try_for_each(|attr| {
|
||||
attr.parse_nested_meta(|meta| {
|
||||
if meta.path.is_ident("enum_name") {
|
||||
let litstr: LitStr = meta.value()?.parse()?;
|
||||
ident = syn::parse_str(&litstr.value()).unwrap();
|
||||
} else {
|
||||
// Reads the value expression to advance the parse stream.
|
||||
// Some parameters, such as `primary_key`, do not have any value,
|
||||
// so ignoring an error occurred here.
|
||||
let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ident
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.collect();
|
||||
})?;
|
||||
Ok::<Ident, syn::Error>(ident)
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
let ty: Vec<Type> = fields.into_iter().map(|Field { ty, .. }| ty).collect();
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use heck::{ToLowerCamelCase, ToSnakeCase};
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{quote, quote_spanned};
|
||||
use syn::{punctuated::Punctuated, token::Comma, Data, DataEnum, Fields, Lit, Meta, Variant};
|
||||
use syn::{Data, DataEnum, Expr, Fields, LitStr, Variant};
|
||||
|
||||
/// Derive a Column name for an enum type
|
||||
pub fn impl_default_as_str(ident: &Ident, data: &Data) -> syn::Result<TokenStream> {
|
||||
@ -28,36 +28,24 @@ pub fn impl_default_as_str(ident: &Ident, data: &Data) -> syn::Result<TokenStrea
|
||||
.map(|v| {
|
||||
let mut column_name = v.ident.to_string().to_snake_case();
|
||||
for attr in v.attrs.iter() {
|
||||
if let Some(ident) = attr.path.get_ident() {
|
||||
if ident != "sea_orm" {
|
||||
if !attr.path().is_ident("sea_orm") {
|
||||
continue;
|
||||
}
|
||||
attr.parse_nested_meta(|meta| {
|
||||
if meta.path.is_ident("column_name") {
|
||||
column_name = meta.value()?.parse::<LitStr>()?.value();
|
||||
} else {
|
||||
continue;
|
||||
// Reads the value expression to advance the parse stream.
|
||||
// Some parameters, such as `primary_key`, do not have any value,
|
||||
// so ignoring an error occurred here.
|
||||
let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();
|
||||
}
|
||||
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();
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
}
|
||||
if name == "table_name" {
|
||||
if let Lit::Str(litstr) = &nv.lit {
|
||||
column_name = litstr.value();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
quote! { #column_name }
|
||||
Ok::<TokenStream, syn::Error>(quote! { #column_name })
|
||||
})
|
||||
.collect();
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
Ok(quote!(
|
||||
#[automatically_derived]
|
||||
|
@ -3,8 +3,8 @@ use heck::{ToSnakeCase, ToUpperCamelCase};
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::{quote, quote_spanned};
|
||||
use syn::{
|
||||
parse::Error, punctuated::Punctuated, spanned::Spanned, token::Comma, Attribute, Data, Fields,
|
||||
Lit, LitStr, Meta, Type,
|
||||
punctuated::Punctuated, spanned::Spanned, token::Comma, Attribute, Data, Expr, Fields, Lit,
|
||||
LitStr, Type,
|
||||
};
|
||||
|
||||
/// Method to derive an Model
|
||||
@ -13,32 +13,28 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
||||
let mut table_name = None;
|
||||
let mut schema_name = quote! { None };
|
||||
let mut table_iden = false;
|
||||
attrs.iter().for_each(|attr| {
|
||||
if attr.path.get_ident().map(|i| i == "sea_orm") != Some(true) {
|
||||
return;
|
||||
attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.path().is_ident("sea_orm"))
|
||||
.try_for_each(|attr| {
|
||||
attr.parse_nested_meta(|meta| {
|
||||
if meta.path.is_ident("table_name") {
|
||||
table_name = Some(meta.value()?.parse::<Lit>()?);
|
||||
} else if meta.path.is_ident("schema_name") {
|
||||
let name: Lit = meta.value()?.parse()?;
|
||||
schema_name = quote! { Some(#name) };
|
||||
} else if meta.path.is_ident("table_iden") {
|
||||
table_iden = true;
|
||||
} else {
|
||||
// Reads the value expression to advance the parse stream.
|
||||
// Some parameters, such as `primary_key`, do not have any value,
|
||||
// so ignoring an error occurred here.
|
||||
let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();
|
||||
}
|
||||
|
||||
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(ident) = nv.path.get_ident() {
|
||||
if ident == "table_name" {
|
||||
table_name = Some(nv.lit.clone());
|
||||
} else if ident == "schema_name" {
|
||||
let name = &nv.lit;
|
||||
schema_name = quote! { Some(#name) };
|
||||
}
|
||||
}
|
||||
} else if let Meta::Path(path) = meta {
|
||||
if let Some(ident) = path.get_ident() {
|
||||
if ident == "table_iden" {
|
||||
table_iden = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
})
|
||||
})?;
|
||||
let entity_def = table_name
|
||||
.as_ref()
|
||||
.map(|table_name| {
|
||||
@ -114,111 +110,86 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
||||
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() {
|
||||
if let Some(ident) = attr.path.get_ident() {
|
||||
if ident != "sea_orm" {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if !attr.path().is_ident("sea_orm") {
|
||||
continue;
|
||||
}
|
||||
|
||||
// single param
|
||||
if let Ok(list) =
|
||||
attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)
|
||||
{
|
||||
for meta in list.iter() {
|
||||
match meta {
|
||||
Meta::NameValue(nv) => {
|
||||
if let Some(name) = nv.path.get_ident() {
|
||||
if name == "column_type" {
|
||||
if let Lit::Str(litstr) = &nv.lit {
|
||||
let ty: TokenStream =
|
||||
syn::parse_str(&litstr.value())?;
|
||||
attr.parse_nested_meta(|meta| {
|
||||
if meta.path.is_ident("column_type") {
|
||||
let lit = meta.value()?.parse()?;
|
||||
if let Lit::Str(litstr) = lit {
|
||||
let ty: TokenStream = syn::parse_str(&litstr.value())?;
|
||||
sql_type = Some(ty);
|
||||
} else {
|
||||
return Err(Error::new(
|
||||
field.span(),
|
||||
format!("Invalid column_type {:?}", nv.lit),
|
||||
));
|
||||
return Err(
|
||||
meta.error(format!("Invalid column_type {:?}", lit))
|
||||
);
|
||||
}
|
||||
} else if name == "auto_increment" {
|
||||
if let Lit::Bool(litbool) = &nv.lit {
|
||||
} else if meta.path.is_ident("auto_increment") {
|
||||
let lit = meta.value()?.parse()?;
|
||||
if let Lit::Bool(litbool) = lit {
|
||||
auto_increment = litbool.value();
|
||||
} else {
|
||||
return Err(Error::new(
|
||||
field.span(),
|
||||
format!(
|
||||
"Invalid auto_increment = {:?}",
|
||||
nv.lit
|
||||
),
|
||||
));
|
||||
return Err(
|
||||
meta.error(format!("Invalid auto_increment = {:?}", lit))
|
||||
);
|
||||
}
|
||||
} else if name == "default_value" {
|
||||
default_value = Some(nv.lit.to_owned());
|
||||
} else if name == "default_expr" {
|
||||
default_expr = Some(nv.lit.to_owned());
|
||||
} else if name == "column_name" {
|
||||
if let Lit::Str(litstr) = &nv.lit {
|
||||
} else if meta.path.is_ident("default_value") {
|
||||
default_value = Some(meta.value()?.parse::<Lit>()?);
|
||||
} else if meta.path.is_ident("default_expr") {
|
||||
default_expr = Some(meta.value()?.parse::<Lit>()?);
|
||||
} else if meta.path.is_ident("column_name") {
|
||||
let lit = meta.value()?.parse()?;
|
||||
if let Lit::Str(litstr) = lit {
|
||||
column_name = Some(litstr.value());
|
||||
} else {
|
||||
return Err(Error::new(
|
||||
field.span(),
|
||||
format!("Invalid column_name {:?}", nv.lit),
|
||||
));
|
||||
return Err(
|
||||
meta.error(format!("Invalid column_name {:?}", lit))
|
||||
);
|
||||
}
|
||||
} else if name == "enum_name" {
|
||||
if let Lit::Str(litstr) = &nv.lit {
|
||||
let ty: Ident =
|
||||
syn::parse_str(&litstr.value())?;
|
||||
} else if meta.path.is_ident("enum_name") {
|
||||
let lit = meta.value()?.parse()?;
|
||||
if let Lit::Str(litstr) = 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),
|
||||
));
|
||||
return Err(meta.error(format!("Invalid enum_name {:?}", lit)));
|
||||
}
|
||||
} else if name == "select_as" {
|
||||
if let Lit::Str(litstr) = &nv.lit {
|
||||
} else if meta.path.is_ident("select_as") {
|
||||
let lit = meta.value()?.parse()?;
|
||||
if let Lit::Str(litstr) = lit {
|
||||
select_as = Some(litstr.value());
|
||||
} else {
|
||||
return Err(Error::new(
|
||||
field.span(),
|
||||
format!("Invalid select_as {:?}", nv.lit),
|
||||
));
|
||||
return Err(meta.error(format!("Invalid select_as {:?}", lit)));
|
||||
}
|
||||
} else if name == "save_as" {
|
||||
if let Lit::Str(litstr) = &nv.lit {
|
||||
} else if meta.path.is_ident("save_as") {
|
||||
let lit = meta.value()?.parse()?;
|
||||
if let Lit::Str(litstr) = lit {
|
||||
save_as = Some(litstr.value());
|
||||
} else {
|
||||
return Err(Error::new(
|
||||
field.span(),
|
||||
format!("Invalid save_as {:?}", nv.lit),
|
||||
));
|
||||
return Err(meta.error(format!("Invalid save_as {:?}", lit)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Meta::Path(p) => {
|
||||
if let Some(name) = p.get_ident() {
|
||||
if name == "ignore" {
|
||||
} else if meta.path.is_ident("ignore") {
|
||||
ignore = true;
|
||||
break;
|
||||
} else if name == "primary_key" {
|
||||
} else if meta.path.is_ident("primary_key") {
|
||||
is_primary_key = true;
|
||||
primary_key_types.push(field.ty.clone());
|
||||
} else if name == "nullable" {
|
||||
} else if meta.path.is_ident("nullable") {
|
||||
nullable = true;
|
||||
} else if name == "indexed" {
|
||||
} else if meta.path.is_ident("indexed") {
|
||||
indexed = true;
|
||||
} else if name == "unique" {
|
||||
} else if meta.path.is_ident("unique") {
|
||||
unique = true;
|
||||
} else {
|
||||
// Reads the value expression to advance the parse stream.
|
||||
// Some parameters, such as `primary_key`, do not have any value,
|
||||
// so ignoring an error occurred here.
|
||||
let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
|
||||
if let Some(enum_name) = enum_name {
|
||||
|
@ -6,7 +6,7 @@ use heck::ToUpperCamelCase;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote, quote_spanned};
|
||||
use std::iter::FromIterator;
|
||||
use syn::{punctuated::Punctuated, token::Comma, Ident, Lit, Meta};
|
||||
use syn::{Expr, Ident, LitStr};
|
||||
|
||||
enum Error {
|
||||
InputNotStruct,
|
||||
@ -50,33 +50,29 @@ impl DeriveModel {
|
||||
let ident = trim_starting_raw_identifier(ident).to_upper_camel_case();
|
||||
let ident = escape_rust_keyword(ident);
|
||||
let mut ident = format_ident!("{}", &ident);
|
||||
for attr in field.attrs.iter() {
|
||||
if let Some(ident) = attr.path.get_ident() {
|
||||
if ident != "sea_orm" {
|
||||
continue;
|
||||
}
|
||||
field
|
||||
.attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.path().is_ident("sea_orm"))
|
||||
.try_for_each(|attr| {
|
||||
attr.parse_nested_meta(|meta| {
|
||||
if meta.path.is_ident("enum_name") {
|
||||
ident = syn::parse_str(&meta.value()?.parse::<LitStr>()?.value())
|
||||
.unwrap();
|
||||
} else {
|
||||
continue;
|
||||
// Reads the value expression to advance the parse stream.
|
||||
// Some parameters, such as `primary_key`, do not have any value,
|
||||
// so ignoring an error occurred here.
|
||||
let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();
|
||||
}
|
||||
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
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.collect();
|
||||
.map_err(Error::Syn)
|
||||
})?;
|
||||
Ok(ident)
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
let ignore_attrs = fields
|
||||
.iter()
|
||||
|
@ -50,11 +50,7 @@ impl DerivePartialModel {
|
||||
let mut entity_ident = None;
|
||||
|
||||
for attr in input.attrs.iter() {
|
||||
if let Some(ident) = attr.path.get_ident() {
|
||||
if ident != "sea_orm" {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if !attr.path().is_ident("sea_orm") {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -77,7 +73,7 @@ impl DerivePartialModel {
|
||||
let mut from_expr = None;
|
||||
|
||||
for attr in field.attrs.iter() {
|
||||
if !attr.path.is_ident("sea_orm") {
|
||||
if !attr.path().is_ident("sea_orm") {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -192,7 +188,7 @@ pub fn expand_derive_partial_model(input: syn::DeriveInput) -> syn::Result<Token
|
||||
}
|
||||
|
||||
mod util {
|
||||
use syn::{Lit, Meta, MetaNameValue};
|
||||
use syn::{Meta, MetaNameValue};
|
||||
|
||||
pub(super) trait GetAsKVMeta {
|
||||
fn get_as_kv(&self, k: &str) -> Option<String>;
|
||||
@ -200,12 +196,14 @@ mod util {
|
||||
|
||||
impl GetAsKVMeta for Meta {
|
||||
fn get_as_kv(&self, k: &str) -> Option<String> {
|
||||
let Meta::NameValue(MetaNameValue{path, lit:Lit::Str(lit), ..}) = self else {
|
||||
let Meta::NameValue(MetaNameValue{path, value: syn::Expr::Lit(exprlit), ..}) = self else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let syn::Lit::Str(litstr) = &exprlit.lit else { return None; };
|
||||
|
||||
if path.is_ident(k) {
|
||||
Some(lit.value())
|
||||
Some(litstr.value())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use heck::ToSnakeCase;
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{quote, quote_spanned};
|
||||
use syn::{punctuated::Punctuated, token::Comma, Data, DataEnum, Fields, Lit, Meta, Variant};
|
||||
use syn::{Data, DataEnum, Expr, Fields, LitStr, Variant};
|
||||
|
||||
/// Method to derive a Primary Key for a Model using the [PrimaryKeyTrait](sea_orm::PrimaryKeyTrait)
|
||||
pub fn expand_derive_primary_key(ident: Ident, data: Data) -> syn::Result<TokenStream> {
|
||||
@ -34,31 +34,26 @@ pub fn expand_derive_primary_key(ident: Ident, data: Data) -> syn::Result<TokenS
|
||||
.map(|v| {
|
||||
let mut column_name = v.ident.to_string().to_snake_case();
|
||||
for attr in v.attrs.iter() {
|
||||
if let Some(ident) = attr.path.get_ident() {
|
||||
if ident != "sea_orm" {
|
||||
if !attr.path().is_ident("sea_orm") {
|
||||
continue;
|
||||
}
|
||||
|
||||
attr.parse_nested_meta(|meta| {
|
||||
if meta.path.is_ident("column_name") {
|
||||
column_name = meta.value()?.parse::<LitStr>()?.value();
|
||||
} else {
|
||||
continue;
|
||||
// Reads the value expression to advance the parse stream.
|
||||
// Some parameters, such as `primary_key`, do not have any value,
|
||||
// so ignoring an error occurred here.
|
||||
let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();
|
||||
}
|
||||
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();
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
quote! { #column_name }
|
||||
Ok::<TokenStream, syn::Error>(quote! { #column_name })
|
||||
})
|
||||
.collect();
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
Ok(quote!(
|
||||
#[automatically_derived]
|
||||
|
@ -4,7 +4,7 @@ use syn::{punctuated::Punctuated, token::Comma, Field, Ident, Meta};
|
||||
|
||||
pub(crate) fn field_not_ignored(field: &Field) -> bool {
|
||||
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" {
|
||||
continue;
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use proc_macro2::TokenStream;
|
||||
use syn::{
|
||||
parenthesized,
|
||||
parse::{Parse, ParseStream},
|
||||
parse2, parse_str,
|
||||
punctuated::Punctuated,
|
||||
spanned::Spanned,
|
||||
Attribute, DeriveInput, Ident, Lit, LitBool, LitStr, Meta, MetaNameValue, Path, Token, Variant,
|
||||
Visibility,
|
||||
Attribute, DeriveInput, Expr, ExprLit, Ident, Lit, LitBool, LitStr, Meta, MetaNameValue, Path,
|
||||
Token, Variant, Visibility,
|
||||
};
|
||||
|
||||
use super::case_style::CaseStyle;
|
||||
@ -76,17 +75,6 @@ impl Parse for EnumMeta {
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for EnumMeta {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
EnumMeta::SerializeAll { kw, .. } => kw.span(),
|
||||
EnumMeta::AsciiCaseInsensitive(kw) => kw.span(),
|
||||
EnumMeta::Crate { kw, .. } => kw.span(),
|
||||
EnumMeta::UsePhf(use_phf) => use_phf.span(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum EnumDiscriminantsMeta {
|
||||
Derive { kw: kw::derive, paths: Vec<Path> },
|
||||
Name { kw: kw::name, name: Ident },
|
||||
@ -100,7 +88,7 @@ impl Parse for EnumDiscriminantsMeta {
|
||||
let kw = input.parse()?;
|
||||
let content;
|
||||
parenthesized!(content in input);
|
||||
let paths = content.parse_terminated::<_, Token![,]>(Path::parse)?;
|
||||
let paths = content.parse_terminated(Path::parse, Token![,])?;
|
||||
Ok(EnumDiscriminantsMeta::Derive {
|
||||
kw,
|
||||
paths: paths.into_iter().collect(),
|
||||
@ -127,17 +115,6 @@ impl Parse for EnumDiscriminantsMeta {
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for EnumDiscriminantsMeta {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
EnumDiscriminantsMeta::Derive { kw, .. } => kw.span,
|
||||
EnumDiscriminantsMeta::Name { kw, .. } => kw.span,
|
||||
EnumDiscriminantsMeta::Vis { kw, .. } => kw.span,
|
||||
EnumDiscriminantsMeta::Other { path, .. } => path.span(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DeriveInputExt {
|
||||
/// Get all the strum metadata associated with an enum.
|
||||
fn get_metadata(&self) -> syn::Result<Vec<EnumMeta>>;
|
||||
@ -228,7 +205,7 @@ impl Parse for VariantMeta {
|
||||
let kw = input.parse()?;
|
||||
let content;
|
||||
parenthesized!(content in input);
|
||||
let props = content.parse_terminated::<_, Token![,]>(Prop::parse)?;
|
||||
let props = content.parse_terminated(Prop::parse, Token![,])?;
|
||||
Ok(VariantMeta::Props {
|
||||
kw,
|
||||
props: props
|
||||
@ -256,22 +233,6 @@ impl Parse for Prop {
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for VariantMeta {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
VariantMeta::Message { kw, .. } => kw.span,
|
||||
VariantMeta::DetailedMessage { kw, .. } => kw.span,
|
||||
VariantMeta::Documentation { value } => value.span(),
|
||||
VariantMeta::Serialize { kw, .. } => kw.span,
|
||||
VariantMeta::ToString { kw, .. } => kw.span,
|
||||
VariantMeta::Disabled(kw) => kw.span,
|
||||
VariantMeta::Default(kw) => kw.span,
|
||||
VariantMeta::AsciiCaseInsensitive { kw, .. } => kw.span,
|
||||
VariantMeta::Props { kw, .. } => kw.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait VariantExt {
|
||||
/// Get all the metadata associated with an enum variant.
|
||||
fn get_metadata(&self) -> syn::Result<Vec<VariantMeta>>;
|
||||
@ -282,26 +243,32 @@ impl VariantExt for Variant {
|
||||
let result = get_metadata_inner("strum", &self.attrs)?;
|
||||
self.attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.path.is_ident("doc"))
|
||||
.filter(|attr| attr.path().is_ident("doc"))
|
||||
.try_fold(result, |mut vec, attr| {
|
||||
if let Meta::NameValue(MetaNameValue {
|
||||
value:
|
||||
Expr::Lit(ExprLit {
|
||||
lit: Lit::Str(value),
|
||||
..
|
||||
}) = attr.parse_meta()?
|
||||
}),
|
||||
..
|
||||
}) = &attr.meta
|
||||
{
|
||||
vec.push(VariantMeta::Documentation { value })
|
||||
vec.push(VariantMeta::Documentation {
|
||||
value: value.clone(),
|
||||
})
|
||||
}
|
||||
Ok(vec)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn get_metadata_inner<'a, T: Parse + Spanned>(
|
||||
fn get_metadata_inner<'a, T: Parse>(
|
||||
ident: &str,
|
||||
it: impl IntoIterator<Item = &'a Attribute>,
|
||||
) -> syn::Result<Vec<T>> {
|
||||
it.into_iter()
|
||||
.filter(|attr| attr.path.is_ident(ident))
|
||||
.filter(|attr| attr.path().is_ident(ident))
|
||||
.try_fold(Vec::new(), |mut vec, attr| {
|
||||
vec.extend(attr.parse_args_with(Punctuated::<T, Token![,]>::parse_terminated)?);
|
||||
Ok(vec)
|
||||
|
Loading…
x
Reference in New Issue
Block a user