From b6109c00fcb13a27e06387ce2ef417a54c24cf3f Mon Sep 17 00:00:00 2001 From: Eric Seppanen Date: Wed, 2 Jun 2021 18:17:15 -0700 Subject: [PATCH] add custom derives callback This callback allows us to specify arbitrary derive attributes for each named struct. This is useful for adding things that can't easily be implemented separately, such as `serde::Deserialize` or `zerocopy::FromBytes`. --- src/callbacks.rs | 8 ++++++++ src/codegen/mod.rs | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/src/callbacks.rs b/src/callbacks.rs index e288af4341..9b34544947 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -95,4 +95,12 @@ pub trait ParseCallbacks: fmt::Debug + UnwindSafe { ) -> Option { None } + + /// Provide a list of custom derive attributes. + /// + /// If no additional attributes are wanted, this function should return an + /// empty `Vec`. + fn add_derives(&self, _name: &str) -> Vec { + vec![] + } } diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 515ebf1733..c70c106427 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -2005,6 +2005,15 @@ impl CodeGenerator for CompInfo { let mut derives: Vec<_> = derivable_traits.into(); derives.extend(item.annotations().derives().iter().map(String::as_str)); + // The custom derives callback may return a list of derive attributes; + // add them to the end of the list. + let custom_derives; + if let Some(cb) = &ctx.options().parse_callbacks { + custom_derives = cb.add_derives(&canonical_name); + // In most cases this will be a no-op, since custom_derives will be empty. + derives.extend(custom_derives.iter().map(|s| s.as_str())); + }; + if !derives.is_empty() { attributes.push(attributes::derives(&derives)) }