diff --git a/Cargo.toml b/Cargo.toml index b3ff555..ec341b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ members = [ [workspace.package] authors = ["Antonio Yang "] -version = "0.2.3" +version = "0.3.0" edition = "2021" categories = ["development-tools"] keywords = ["struct", "patch", "macro", "derive", "overlay"] diff --git a/flake.lock b/flake.lock index 8a55ad2..72da384 100644 --- a/flake.lock +++ b/flake.lock @@ -51,12 +51,15 @@ } }, "flake-utils_3": { + "inputs": { + "systems": "systems" + }, "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "lastModified": 1687171271, + "narHash": "sha256-BJlq+ozK2B1sJDQXS3tzJM5a+oVZmi1q0FlBK/Xqv7M=", "owner": "numtide", "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "rev": "abfb11bd1aec8ced1c9bb9adfe68018230f4fb3c", "type": "github" }, "original": { @@ -66,12 +69,15 @@ } }, "flake-utils_4": { + "inputs": { + "systems": "systems_2" + }, "locked": { - "lastModified": 1659877975, - "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", "owner": "numtide", "repo": "flake-utils", - "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", "type": "github" }, "original": { @@ -114,11 +120,11 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1673796341, - "narHash": "sha256-1kZi9OkukpNmOaPY7S5/+SlCDOuYnP3HkXHvNDyLQcc=", + "lastModified": 1687412861, + "narHash": "sha256-Z/g0wbL68C+mSGerYS2quv9FXQ1RRP082cAC0Bh4vcs=", "owner": "nixos", "repo": "nixpkgs", - "rev": "6dccdc458512abce8d19f74195bb20fdb067df50", + "rev": "e603dc5f061ca1d8a19b3ede6a8cf9c9fcba6cdc", "type": "github" }, "original": { @@ -130,11 +136,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1665296151, - "narHash": "sha256-uOB0oxqxN9K7XGF1hcnY+PQnlQJ+3bP2vCn/+Ru/bbc=", + "lastModified": 1681358109, + "narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "14ccaaedd95a488dd7ae142757884d8e125b3363", + "rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9", "type": "github" }, "original": { @@ -177,11 +183,11 @@ "nixpkgs": "nixpkgs_4" }, "locked": { - "lastModified": 1673922364, - "narHash": "sha256-U0XIY/Y/x4fFtlCZKMtWlqOYUnLiXj4F42GQHxWuPow=", + "lastModified": 1687400833, + "narHash": "sha256-rVENiSupjAE8o1+ZXNRIqewUzM2brm+aeme8MUrwl0U=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "4e0f9b8a5102387f8d19901bced16a256a6ccdc7", + "rev": "fc0a266e836c079a9131108f4334e5af219dbb93", "type": "github" }, "original": { @@ -189,6 +195,36 @@ "repo": "rust-overlay", "type": "github" } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index a553a61..5c97f87 100644 --- a/flake.nix +++ b/flake.nix @@ -14,7 +14,7 @@ pkgs = import nixpkgs { inherit system overlays; }; - rust = pkgs.rust-bin.stable."1.64.0".default; + rust = pkgs.rust-bin.stable."1.69.0".default; dr = dependency-refresh.defaultPackage.${system}; publishScript = pkgs.writeShellScriptBin "crate-publish" '' diff --git a/struct-patch-derive/Cargo.toml b/struct-patch-derive/Cargo.toml index ce07891..abf969c 100644 --- a/struct-patch-derive/Cargo.toml +++ b/struct-patch-derive/Cargo.toml @@ -17,7 +17,7 @@ proc-macro = true proc-macro2 = "1.0" quote = "1.0" proc-macro-error = "1.0" -syn = { version = "1.0", features = ["parsing"] } +syn = { version = "2.0", features = ["parsing"] } [features] status = [] diff --git a/struct-patch-derive/src/lib.rs b/struct-patch-derive/src/lib.rs index 0c1e77c..b3ba6a4 100644 --- a/struct-patch-derive/src/lib.rs +++ b/struct-patch-derive/src/lib.rs @@ -1,9 +1,10 @@ extern crate proc_macro; use proc_macro::TokenStream; -use proc_macro2::{Ident, Span, TokenTree}; +use proc_macro2::{Ident, Span}; use proc_macro_error::{abort, proc_macro_error}; use quote::quote; +use syn::{Expr, Lit, Meta, MetaList, MetaNameValue, PathSegment}; #[proc_macro_derive(Patch, attributes(patch_derive, patch_name, patch_skip))] #[proc_macro_error] @@ -13,25 +14,65 @@ pub fn derive_patch(item: TokenStream) -> TokenStream { let mut patch_struct_name = None; let mut patch_derive = None; let attrs = input.attrs; - for syn::Attribute { path, tokens, .. } in attrs { - match path - .segments - .first() - .map(|s| s.ident.to_string()) - .as_deref() - { - Some("patch_derive") => { - patch_derive = Some(tokens); + + for attr in attrs { + let mut attr_clone = attr.clone(); + let syn::Attribute { meta, .. } = attr; + match meta { + Meta::List(MetaList { + path, + tokens, + delimiter, + }) => { + let mut path_clone = path.clone(); + let mut segments = path.segments.clone(); + match path + .segments + .first() + .map(|s| s.ident.to_string()) + .as_deref() + { + Some("patch_derive") => { + if let Some(seg) = segments.first_mut() { + *seg = PathSegment { + ident: Ident::new("derive", Span::call_site()), + arguments: seg.arguments.clone(), + }; + } + path_clone.segments = segments; + attr_clone.meta = Meta::List(MetaList { + path: path_clone, + tokens, + delimiter, + }); + patch_derive = Some(attr_clone); + } + _ => {} + } } - Some("patch_name") => { - if let Some(TokenTree::Literal(l)) = tokens.clone().into_iter().nth(1) { - patch_struct_name = Some(Ident::new( - format!("{}", l).trim_matches('"'), - Span::call_site(), - )); + Meta::NameValue(MetaNameValue { + path, + value: Expr::Lit(lit, ..), + .. + }) => { + match path + .segments + .first() + .map(|s| s.ident.to_string()) + .as_deref() + { + Some("patch_name") => { + if let Lit::Str(l) = lit.lit { + patch_struct_name = Some(Ident::new( + format!("{}", l.value()).trim_matches('"'), + Span::call_site(), + )); + } + } + _ => {} } } - _ => {} + _ => (), } } @@ -63,12 +104,16 @@ pub fn derive_patch(item: TokenStream) -> TokenStream { let wrapped_fields = &mut fields_with_type .iter() .filter_map(|(f, t, attrs)| { - if attrs.iter().any(|syn::Attribute { path, .. }| { - path.segments - .first() - .map(|s| s.ident.to_string()) - .as_deref() - == Some("patch_skip") + if attrs.iter().any(|syn::Attribute { meta, .. }| { + if let Meta::Path(path) = meta { + path.segments + .first() + .map(|s| s.ident.to_string()) + .as_deref() + == Some("patch_skip") + } else { + false + } }) { None } else { @@ -88,9 +133,9 @@ pub fn derive_patch(item: TokenStream) -> TokenStream { let patch_struct_name = patch_struct_name .unwrap_or_else(|| Ident::new(&format!("{}Patch", struct_name), Span::call_site())); - let patch_struct = Some(if let Some(patch_derive) = patch_derive { + let patch_struct = if let Some(patch_derive) = patch_derive { quote!( - #[derive #patch_derive] + #patch_derive pub struct #patch_struct_name { #(pub #field_names: #wrapped_types,)* } @@ -101,11 +146,11 @@ pub fn derive_patch(item: TokenStream) -> TokenStream { #(pub #field_names: #wrapped_types,)* } ) - }); + }; #[cfg(feature = "status")] let patch_status_impl = quote!( - impl struct_patch::PatchStatus for #patch_struct_name { + impl struct_patch::traits::PatchStatus for #patch_struct_name { fn is_empty(&self) -> bool { #( if self.#field_names.is_some() { @@ -120,7 +165,7 @@ pub fn derive_patch(item: TokenStream) -> TokenStream { let patch_status_impl = quote!(); let patch_impl = quote! { - impl struct_patch::Patch< #patch_struct_name > for #struct_name { + impl struct_patch::traits::Patch< #patch_struct_name > for #struct_name { fn apply(&mut self, patch: #patch_struct_name) { #( if let Some(v) = patch.#field_names { diff --git a/struct-patch/Cargo.toml b/struct-patch/Cargo.toml index f284c79..cc3be5a 100644 --- a/struct-patch/Cargo.toml +++ b/struct-patch/Cargo.toml @@ -11,7 +11,7 @@ license.workspace = true readme.workspace = true [dependencies] -struct-patch-derive = { version = "=0.2.3", path = "../struct-patch-derive" } +struct-patch-derive = { version = "=0.3.0", path = "../struct-patch-derive" } [dev-dependencies] serde_json = "1.0"