diff --git a/src/imp.rs b/src/imp.rs index 2c56e4d..2833f8d 100644 --- a/src/imp.rs +++ b/src/imp.rs @@ -251,7 +251,26 @@ fn strike_through_attributes( true } }); - dec_attrs.extend_from_slice(&strike_attrs[..]); + + let (mut derive_attrs, rest_attrs) = + strike_attrs + .iter() + .fold((Vec::new(), Vec::new()), |(mut der, mut rest), i| { + if matches!(&i.path[0], TokenTree::Ident(token) if token == "derive") { + der.push(i.clone()); + } else { + rest.push(i.clone()); + } + (der, rest) + }); + + // place other attrs after the existing ones + dec_attrs.extend_from_slice(&rest_attrs[..]); + + // insert derive attrs before attributes + derive_attrs + .drain(..) + .for_each(|attr| dec_attrs.insert(0, attr)); } fn recurse_through_type_list( diff --git a/src/test.rs b/src/test.rs index 067c9f7..b7d2796 100644 --- a/src/test.rs +++ b/src/test.rs @@ -12,6 +12,7 @@ fn check(nested: proc_macro2::TokenStream, planexpected: proc_macro2::TokenStrea #[test] fn strikethrough_derive() { let from = quote! { + #[strikethrough[striked_attr]] #[strikethrough[derive(Debug, Default, PartialEq)]] #[gubbel] struct Parent { @@ -22,19 +23,23 @@ fn strikethrough_derive() { e: u32, } }; + let out = quote! { #[derive(Debug, Default, PartialEq)] + #[striked_attr] struct Shared { d: i32 } - #[gobbel] #[derive(Debug, Default, PartialEq)] + #[gobbel] + #[striked_attr] struct A { b: Shared, c: Shared, } - #[gubbel] #[derive(Debug, Default, PartialEq)] + #[gubbel] + #[striked_attr] struct Parent { a: A, e: u32,