diff --git a/miniconf_derive/Cargo.toml b/miniconf_derive/Cargo.toml index d8b23ad7..a80530ee 100644 --- a/miniconf_derive/Cargo.toml +++ b/miniconf_derive/Cargo.toml @@ -13,6 +13,6 @@ categories = ["no-std", "config", "rust-patterns", "parsing"] proc-macro = true [dependencies] -syn = { version = "1.0.58", features = ["extra-traits"] } -quote = "1.0.8" -proc-macro2 = "1.0.24" +syn = { version = "2.0", features = ["extra-traits"] } +quote = "1.0" +proc-macro2 = "1.0" diff --git a/miniconf_derive/src/attributes.rs b/miniconf_derive/src/attributes.rs deleted file mode 100644 index de2c6490..00000000 --- a/miniconf_derive/src/attributes.rs +++ /dev/null @@ -1,45 +0,0 @@ -use proc_macro2::token_stream::IntoIter as TokenIter; -use proc_macro2::{TokenStream, TokenTree}; -use std::str::FromStr; - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum MiniconfAttribute { - Defer, -} - -impl FromStr for MiniconfAttribute { - type Err = String; - fn from_str(s: &str) -> Result { - let attr = match s { - "defer" => MiniconfAttribute::Defer, - other => return Err(format!("Unknown attribute: {other}")), - }; - - Ok(attr) - } -} - -pub struct AttributeParser { - inner: TokenIter, -} - -impl AttributeParser { - pub fn new(stream: TokenStream) -> Self { - Self { - inner: stream.into_iter(), - } - } - - pub fn parse(&mut self) -> MiniconfAttribute { - let first = self.inner.next().expect("A single keyword"); - - match first { - TokenTree::Group(group) => { - let ident: syn::Ident = syn::parse2(group.stream()).expect("An identifier"); - - MiniconfAttribute::from_str(&ident.to_string()).unwrap() - } - other => panic!("Unexpected tree: {:?}", other), - } - } -} diff --git a/miniconf_derive/src/field.rs b/miniconf_derive/src/field.rs index abd5b6e8..7839cc30 100644 --- a/miniconf_derive/src/field.rs +++ b/miniconf_derive/src/field.rs @@ -1,4 +1,3 @@ -use super::attributes::{AttributeParser, MiniconfAttribute}; use syn::{parse_quote, Generics}; pub struct StructField { @@ -8,14 +7,21 @@ pub struct StructField { impl StructField { pub fn new(field: syn::Field) -> Self { - let attributes: Vec = field - .attrs - .iter() - .filter(|attr| attr.path.is_ident("miniconf")) - .map(|attr| AttributeParser::new(attr.tokens.clone()).parse()) - .collect(); + let mut deferred = false; - let deferred = attributes.iter().any(|x| *x == MiniconfAttribute::Defer); + for attr in field.attrs.iter() { + if attr.path().is_ident("miniconf") { + attr.parse_nested_meta(|meta| { + if meta.path.is_ident("defer") { + deferred = true; + Ok(()) + } else { + Err(meta.error(format!("unrecognized miniconf attribute {:?}", meta.path))) + } + }) + .unwrap(); + } + } Self { deferred, field } } diff --git a/miniconf_derive/src/lib.rs b/miniconf_derive/src/lib.rs index 7452f2aa..9b9df878 100644 --- a/miniconf_derive/src/lib.rs +++ b/miniconf_derive/src/lib.rs @@ -2,7 +2,6 @@ use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, DeriveInput}; -mod attributes; mod field; use field::StructField; diff --git a/src/lib.rs b/src/lib.rs index 9b1f096e..5903b936 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,10 +16,10 @@ pub use serde; // Re-exports #[cfg(feature = "json")] -pub use serde_json_core; -#[cfg(feature = "json")] pub use heapless; #[cfg(feature = "json")] +pub use serde_json_core; +#[cfg(feature = "json")] mod json; #[cfg(feature = "json")] pub use json::JsonCoreSlash;