diff --git a/Cargo.toml b/Cargo.toml index 5f84504..b159d7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ proc-macro = true miniserde = "0.1" [dependencies] -syn = { version = "1.0", features = ["derive", "full"] } +syn = { version = "2", features = ["derive", "full"] } quote = "1.0" proc-macro2 = "1.0" miniserde = "0.1" # TODO: remove diff --git a/src/attr.rs b/src/attr.rs index 2781320..0245f49 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -1,5 +1,5 @@ use crate::TagType; -use syn::{Attribute, DataEnum, Error, Field, Fields, Lit, Meta, NestedMeta, Result, Variant}; +use syn::{Attribute, DataEnum, Error, Field, Fields, LitStr, Result, Variant}; pub(crate) fn tag_type(attrs: &[Attribute], enumeration: &DataEnum) -> Result { let mut tag_type = None; @@ -7,52 +7,35 @@ pub(crate) fn tag_type(attrs: &[Attribute], enumeration: &DataEnum) -> Result list, - other => return Err(Error::new_spanned(other, "unsupported attribute")), - }; - - for meta in &list.nested { - match meta { - NestedMeta::Meta(Meta::NameValue(value)) => { - if value.path.is_ident("tag") { - if let Lit::Str(s) = &value.lit { - if tag.is_some() { - return Err(Error::new_spanned(meta, "duplicate tag attribute")); - } - tag = Some(s.value()); - continue; - } - } else if value.path.is_ident("content") { - if let Lit::Str(s) = &value.lit { - if content.is_some() { - return Err(Error::new_spanned( - meta, - "duplicate content attribute", - )); - } - content = Some(s.value()); - continue; - } - } + attr.parse_nested_meta(|meta| { + if meta.path.is_ident("tag") { + let value: LitStr = meta.value()?.parse()?; + if tag.is_some() { + return Err(meta.error("duplicate tag attribute")); } - NestedMeta::Meta(Meta::Path(path)) => { - if path.is_ident("untagged") { - if tag_type.is_some() { - return Err(Error::new_spanned(meta, "duplicate tag attribute")); - } - tag_type = Some(TagType::Untagged); - continue; - } - } - _ => (), + tag = Some(value.value()); + return Ok(()); } - return Err(Error::new_spanned(meta, "unsupported attribute")); - } + if meta.path.is_ident("content") { + let value: LitStr = meta.value()?.parse()?; + if content.is_some() { + return Err(meta.error("duplicate content attribute")); + } + content = Some(value.value()); + return Ok(()); + } + if meta.path.is_ident("untagged") { + if tag_type.is_some() { + return Err(meta.error("duplicate tag attribute")); + } + tag_type = Some(TagType::Untagged); + return Ok(()); + } + Err(meta.error("unsupported attribute")) + })?; } if let Some(ty) = tag_type { return Ok(ty); @@ -84,29 +67,20 @@ fn attr_rename(attrs: &[Attribute]) -> Result> { let mut rename = None; for attr in attrs { - if !attr.path.is_ident("serde") { + if !attr.path().is_ident("serde") { continue; } - - let list = match attr.parse_meta()? { - Meta::List(list) => list, - other => return Err(Error::new_spanned(other, "unsupported attribute")), - }; - - for meta in &list.nested { - if let NestedMeta::Meta(Meta::NameValue(value)) = meta { - if value.path.is_ident("rename") { - if let Lit::Str(s) = &value.lit { - if rename.is_some() { - return Err(Error::new_spanned(meta, "duplicate rename attribute")); - } - rename = Some(s.value()); - continue; - } + attr.parse_nested_meta(|meta| { + if meta.path.is_ident("rename") { + let value: LitStr = meta.value()?.parse()?; + if rename.is_some() { + return Err(meta.error("duplicate rename attribute")); } + rename = Some(value.value()); + return Ok(()); } - return Err(Error::new_spanned(meta, "unsupported attribute")); - } + Err(meta.error("unsupported attribute")) + })?; } Ok(rename) diff --git a/src/bound.rs b/src/bound.rs index a48305c..08dc491 100644 --- a/src/bound.rs +++ b/src/bound.rs @@ -1,13 +1,13 @@ use proc_macro2::{Span, TokenStream}; use syn::punctuated::Punctuated; use syn::{ - parse_quote, GenericParam, Generics, Lifetime, LifetimeDef, TypeParamBound, WhereClause, + parse_quote, GenericParam, Generics, Lifetime, LifetimeParam, TypeParamBound, WhereClause, WherePredicate, }; pub fn with_lifetime_bound(generics: &Generics, lifetime: &str) -> Generics { let bound = Lifetime::new(lifetime, Span::call_site()); - let def = LifetimeDef { + let def = LifetimeParam { attrs: Vec::new(), lifetime: bound.clone(), colon_token: None,