diff --git a/sea-orm-codegen/Cargo.toml b/sea-orm-codegen/Cargo.toml index d6c27276..cb97dbf9 100644 --- a/sea-orm-codegen/Cargo.toml +++ b/sea-orm-codegen/Cargo.toml @@ -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 } diff --git a/sea-orm-macros/Cargo.toml b/sea-orm-macros/Cargo.toml index 4091a834..18de5576 100644 --- a/sea-orm-macros/Cargo.toml +++ b/sea-orm-macros/Cargo.toml @@ -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 } diff --git a/sea-orm-macros/src/derives/active_enum.rs b/sea-orm-macros/src/derives/active_enum.rs index aa85f8a9..77e30196 100644 --- a/sea-orm-macros/src/derives/active_enum.rs +++ b/sea-orm-macros/src/derives/active_enum.rs @@ -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,51 +37,46 @@ 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::::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::(&litstr.value()) - .map_err(Error::Syn); - } - } else if name == "db_type" { - if let Lit::Str(litstr) = &nv.lit { - let s = litstr.value(); - match s.as_ref() { - "Enum" => { - db_type = Ok(quote! { - Enum { - name: Self::name(), - variants: Self::iden_values(), - } - }) - } - _ => { - db_type = syn::parse_str::(&s) - .map_err(Error::Syn); - } + + 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::(&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" => { + db_type = Ok(quote! { + Enum { + name: Self::name(), + variants: Self::iden_values(), } - } - } else if name == "enum_name" { - if let Lit::Str(litstr) = &nv.lit { - enum_name = litstr.value(); - } + }) + } + _ => { + db_type = syn::parse_str::(&s).map_err(Error::Syn); } } + } 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" { - continue; - } - } else { + if !attr.path().is_ident("sea_orm") { continue; } - if let Ok(list) = attr.parse_args_with(Punctuated::::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 { - is_string = true; - string_value = Some(lit); - } - } else if name == "num_value" { - if let Lit::Int(lit) = nv.lit { - is_int = true; - num_value = Some(lit); - } - } - } - } + attr.parse_nested_meta(|meta| { + if meta.path.is_ident("string_value") { + is_string = true; + string_value = Some(meta.value()?.parse::()?); + } else if meta.path.is_ident("num_value") { + is_int = true; + num_value = Some(meta.value()?.parse::()?); + } else { + return Err(meta.error(format!( + "Unknown attribute parameter found: {:?}", + meta.path.get_ident() + ))); } - } + + Ok(()) + }) + .map_err(Error::Syn)?; } if is_string && is_int { diff --git a/sea-orm-macros/src/derives/active_model.rs b/sea-orm-macros/src/derives/active_model.rs index dbea86f1..975eabfd 100644 --- a/sea-orm-macros/src/derives/active_model.rs +++ b/sea-orm-macros/src/derives/active_model.rs @@ -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 { @@ -47,32 +43,28 @@ fn derive_active_model(all_fields: IntoIter) -> syn::Result 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::::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(); - } - } - } + 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 = meta.value().and_then(|v| v.parse()).ok(); } - } - } - } - ident + + Ok(()) + }) + })?; + Ok::(ident) }) - .collect(); + .collect::>()?; let ty: Vec = fields.into_iter().map(|Field { ty, .. }| ty).collect(); diff --git a/sea-orm-macros/src/derives/column.rs b/sea-orm-macros/src/derives/column.rs index dbc9017a..f91cf48e 100644 --- a/sea-orm-macros/src/derives/column.rs +++ b/sea-orm-macros/src/derives/column.rs @@ -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 { @@ -28,36 +28,24 @@ pub fn impl_default_as_str(ident: &Ident, data: &Data) -> syn::Result::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(); - } - } - if name == "table_name" { - if let Lit::Str(litstr) = &nv.lit { - column_name = litstr.value(); - } - } - } - } + attr.parse_nested_meta(|meta| { + if meta.path.is_ident("column_name") { + column_name = meta.value()?.parse::()?.value(); + } 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 = meta.value().and_then(|v| v.parse()).ok(); } - } + Ok(()) + })?; } - quote! { #column_name } + Ok::(quote! { #column_name }) }) - .collect(); + .collect::>()?; Ok(quote!( #[automatically_derived] diff --git a/sea-orm-macros/src/derives/entity_model.rs b/sea-orm-macros/src/derives/entity_model.rs index e50b8a66..67cb27e8 100644 --- a/sea-orm-macros/src/derives/entity_model.rs +++ b/sea-orm-macros/src/derives/entity_model.rs @@ -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) -> 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; - } - - if let Ok(list) = attr.parse_args_with(Punctuated::::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; - } - } + 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::()?); + } 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 = meta.value().and_then(|v| v.parse()).ok(); } - } - } - }); + + 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) -> 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::::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())?; - sql_type = Some(ty); - } else { - return Err(Error::new( - field.span(), - format!("Invalid column_type {:?}", nv.lit), - )); - } - } else if name == "auto_increment" { - if let Lit::Bool(litbool) = &nv.lit { - auto_increment = litbool.value(); - } else { - return Err(Error::new( - field.span(), - format!( - "Invalid auto_increment = {:?}", - nv.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 { - 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), - )); - } - } else if name == "select_as" { - if let Lit::Str(litstr) = &nv.lit { - select_as = Some(litstr.value()); - } else { - return Err(Error::new( - field.span(), - format!("Invalid select_as {:?}", nv.lit), - )); - } - } else if name == "save_as" { - if let Lit::Str(litstr) = &nv.lit { - save_as = Some(litstr.value()); - } else { - return Err(Error::new( - field.span(), - format!("Invalid save_as {:?}", nv.lit), - )); - } - } - } - } - Meta::Path(p) => { - if let Some(name) = p.get_ident() { - if name == "ignore" { - ignore = true; - break; - } else if name == "primary_key" { - is_primary_key = true; - primary_key_types.push(field.ty.clone()); - } else if name == "nullable" { - nullable = true; - } else if name == "indexed" { - indexed = true; - } else if name == "unique" { - unique = true; - } - } - } - _ => {} + 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( + meta.error(format!("Invalid column_type {:?}", 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( + meta.error(format!("Invalid auto_increment = {:?}", lit)) + ); + } + } else if meta.path.is_ident("default_value") { + default_value = Some(meta.value()?.parse::()?); + } else if meta.path.is_ident("default_expr") { + default_expr = Some(meta.value()?.parse::()?); + } 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( + meta.error(format!("Invalid column_name {:?}", lit)) + ); + } + } 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(meta.error(format!("Invalid enum_name {:?}", 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(meta.error(format!("Invalid select_as {:?}", 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(meta.error(format!("Invalid save_as {:?}", lit))); + } + } else if meta.path.is_ident("ignore") { + ignore = true; + } else if meta.path.is_ident("primary_key") { + is_primary_key = true; + primary_key_types.push(field.ty.clone()); + } else if meta.path.is_ident("nullable") { + nullable = true; + } else if meta.path.is_ident("indexed") { + indexed = true; + } 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 = meta.value().and_then(|v| v.parse()).ok(); } - } + + Ok(()) + })?; } if let Some(enum_name) = enum_name { diff --git a/sea-orm-macros/src/derives/model.rs b/sea-orm-macros/src/derives/model.rs index d3813f28..b28c62cf 100644 --- a/sea-orm-macros/src/derives/model.rs +++ b/sea-orm-macros/src/derives/model.rs @@ -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; - } - } else { - continue; - } - if let Ok(list) = - attr.parse_args_with(Punctuated::::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(); - } - } - } + 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::()?.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 = meta.value().and_then(|v| v.parse()).ok(); } - } - } - } - ident + + Ok(()) + }) + .map_err(Error::Syn) + })?; + Ok(ident) }) - .collect(); + .collect::>()?; let ignore_attrs = fields .iter() diff --git a/sea-orm-macros/src/derives/partial_model.rs b/sea-orm-macros/src/derives/partial_model.rs index 3d370358..567e633a 100644 --- a/sea-orm-macros/src/derives/partial_model.rs +++ b/sea-orm-macros/src/derives/partial_model.rs @@ -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 Option; @@ -200,12 +196,14 @@ mod util { impl GetAsKVMeta for Meta { fn get_as_kv(&self, k: &str) -> Option { - 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 } diff --git a/sea-orm-macros/src/derives/primary_key.rs b/sea-orm-macros/src/derives/primary_key.rs index 34e183fb..f7ca14f4 100644 --- a/sea-orm-macros/src/derives/primary_key.rs +++ b/sea-orm-macros/src/derives/primary_key.rs @@ -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 { @@ -34,31 +34,26 @@ pub fn expand_derive_primary_key(ident: Ident, data: Data) -> syn::Result::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(); - } - } - } - } + + attr.parse_nested_meta(|meta| { + if meta.path.is_ident("column_name") { + column_name = meta.value()?.parse::()?.value(); + } 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 = meta.value().and_then(|v| v.parse()).ok(); } - } + + Ok(()) + })?; } - quote! { #column_name } + Ok::(quote! { #column_name }) }) - .collect(); + .collect::>()?; Ok(quote!( #[automatically_derived] diff --git a/sea-orm-macros/src/derives/util.rs b/sea-orm-macros/src/derives/util.rs index 7de4b79c..e59203f6 100644 --- a/sea-orm-macros/src/derives/util.rs +++ b/sea-orm-macros/src/derives/util.rs @@ -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; } diff --git a/sea-orm-macros/src/strum/helpers/metadata.rs b/sea-orm-macros/src/strum/helpers/metadata.rs index 56e4c78b..d638ae3c 100644 --- a/sea-orm-macros/src/strum/helpers/metadata.rs +++ b/sea-orm-macros/src/strum/helpers/metadata.rs @@ -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 }, 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>; @@ -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>; @@ -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 { - lit: Lit::Str(value), + 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, ) -> syn::Result> { 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::::parse_terminated)?); Ok(vec)