diff --git a/Cargo.lock b/Cargo.lock index 1ff2fbc6ea..978f0b4291 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,7 +128,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn", ] [[package]] @@ -154,7 +154,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.29", + "syn", ] [[package]] @@ -552,7 +552,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn", ] [[package]] @@ -1234,7 +1234,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn", ] [[package]] @@ -1349,7 +1349,7 @@ version = "0.2.1" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -1358,17 +1358,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.29" @@ -1434,7 +1423,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn", ] [[package]] @@ -1519,7 +1508,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.29", + "syn", "wasm-bindgen-shared", ] @@ -1541,7 +1530,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/stratisd_proc_macros/Cargo.toml b/stratisd_proc_macros/Cargo.toml index 5a25892ccb..8edf49adc1 100644 --- a/stratisd_proc_macros/Cargo.toml +++ b/stratisd_proc_macros/Cargo.toml @@ -19,7 +19,7 @@ proc-macro2 = "1.0.27" quote = "1.0.9" [dependencies.syn] -version = "1.0.73" +version = "2.0.0" features = ["full", "extra-traits"] [lints.rust] diff --git a/stratisd_proc_macros/src/lib.rs b/stratisd_proc_macros/src/lib.rs index cc3c888283..9e6adf0f8f 100644 --- a/stratisd_proc_macros/src/lib.rs +++ b/stratisd_proc_macros/src/lib.rs @@ -8,16 +8,16 @@ use proc_macro::TokenStream; use proc_macro2::{Group, Span, TokenStream as TokenStream2, TokenTree}; use quote::quote; use syn::{ - parse, parse_str, punctuated::Punctuated, token::Comma, Attribute, Block, FnArg, Ident, - ImplItem, ImplItemMethod, Item, Lit, Meta, MetaList, NestedMeta, Pat, PatIdent, PatType, Path, - PathSegment, Receiver, ReturnType, Stmt, Token, Type, TypePath, + parse, punctuated::Punctuated, token::Comma, Attribute, Block, FnArg, Ident, ImplItem, + ImplItemFn, Item, LitStr, Pat, PatIdent, PatType, Path, PathSegment, Receiver, ReturnType, + Stmt, Token, Type, TypePath, }; /// Add guard for mutating actions when the pool is in maintenance mode. /// /// This method adds a statement that returns an error if the pool is set /// to limit available actions. -fn add_method_guards(method: &mut ImplItemMethod, level: Ident) { +fn add_method_guards(method: &mut ImplItemFn, level: Ident) { let stmt = if let ReturnType::Type(_, ty) = &method.sig.output { if let Type::Path(TypePath { path: Path { segments, .. }, @@ -136,7 +136,7 @@ fn process_token_stream(token: TokenTree) -> TokenTree { /// Take the body of the method and wrap it in an inner method, replacing the /// body with a check for an error that limits available actions. -fn wrap_method(f: &mut ImplItemMethod) { +fn wrap_method(f: &mut ImplItemFn) { let wrapped_ident = Ident::new( format!("{}_wrapped", f.sig.ident.clone()).as_str(), Span::call_site(), @@ -190,62 +190,55 @@ fn wrap_method(f: &mut ImplItemMethod) { .expect("Could not parse generated method body as a block"); } -/// Get the pool available action state level at which a pool operation ceases to be -/// accepted. +/// Get the pool available action state level at which a pool operation ceases +/// to be accepted. Panic if there is more than one pool_mutating_action +/// specified. fn get_attr_level(attrs: &mut Vec) -> Option { - let mut return_value = None; - let mut index = None; - for (i, attr) in attrs.iter().enumerate() { - if let Meta::List(MetaList { - ref path, - ref nested, - .. - }) = attr - .parse_meta() - .unwrap_or_else(|_| panic!("Attribute {attr:?} cannot be parsed")) - { - if path - == &parse_str("pool_mutating_action").expect("pool_mutating_action is valid path") - { - for nested_meta in nested.iter() { - if let NestedMeta::Lit(Lit::Str(litstr)) = nested_meta { - index = Some(i); - return_value = - Some(parse_str::(&litstr.value()).unwrap_or_else(|_| { - panic!("{} is not a valid identifier", litstr.value()) - })); - } else { - panic!("pool_mutating_action attribute must be in form #[pool_mutating_action(\"REJECTION LEVEL\")]"); - } - } + let matching_attrs = attrs + .iter() + .enumerate() + .filter(|(_, a)| a.path().is_ident("pool_mutating_action")) + .map(|(i, a)| { + if let Ok(level) = a.parse_args::() { + (i, level.parse::().unwrap_or_else(|_| {panic!("{} is expected to be a valid identifier", level.value())})) + } else { + panic!("pool_mutating_action attribute must be in form #[pool_mutating_action(\"REJECTION LEVEL\")]") } + }).collect::>(); + + match matching_attrs.len() { + 0 => None, + 1 => { + let (index, return_value) = &matching_attrs[0]; + attrs.remove(*index); + Some(return_value.clone()) } + _ => panic!( + "More than 1 pool_mutating_action arguments specified; ambiguous request can not be satisfied." + ), } - if let Some(i) = index { - attrs.remove(i); - } - return_value } /// Determine whether a method has the given attribute. fn has_attribute(attrs: &mut Vec, attribute: &str) -> bool { - let mut return_value = false; - let mut index = None; - for (i, attr) in attrs.iter().enumerate() { - if let Meta::Path(path) = attr - .parse_meta() - .unwrap_or_else(|_| panic!("Attribute {attr:?} cannot be parsed")) - { - if path == parse_str(attribute).expect("pool_mutating_action is valid path") { - index = Some(i); - return_value = true; - } + let matching_attrs = attrs + .iter() + .enumerate() + .filter(|(_, a)| a.path().is_ident(attribute)) + .collect::>(); + + match matching_attrs.len() { + 0 => false, + 1 => { + let (index, _) = matching_attrs[0]; + attrs.remove(index); + true } + _ => panic!( + "More than 1 {} attribute specified for the same syntactic entity.", + attribute + ), } - if let Some(i) = index { - attrs.remove(i); - } - return_value } /// Determine whether a method should be marked as needing to handle failed rollback @@ -265,7 +258,7 @@ fn process_item(mut item: Item) -> Item { }; for impl_item in i.items.iter_mut() { - if let ImplItem::Method(ref mut f) = impl_item { + if let ImplItem::Fn(ref mut f) = impl_item { if let Some(level) = get_attr_level(&mut f.attrs) { add_method_guards(f, level); }