diff --git a/bindgen-tests/Cargo.toml b/bindgen-tests/Cargo.toml index 77a28ca3cb..23f48b39e9 100644 --- a/bindgen-tests/Cargo.toml +++ b/bindgen-tests/Cargo.toml @@ -13,6 +13,7 @@ owo-colors.workspace = true prettyplease = { workspace = true, features = ["verbatim"] } proc-macro2.workspace = true regex.workspace = true +serde.workspace = true shlex.workspace = true similar = { workspace = true, features = ["inline"] } syn.workspace = true diff --git a/bindgen-tests/tests/expectations/tests/derive-and-attribute-order.rs b/bindgen-tests/tests/expectations/tests/derive-and-attribute-order.rs new file mode 100644 index 0000000000..ee807430f3 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-and-attribute-order.rs @@ -0,0 +1,9 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, serde::Serialize)] +#[serde(transparent)] +pub struct color { + pub red: ::std::os::raw::c_int, + pub green: ::std::os::raw::c_int, + pub blue: ::std::os::raw::c_int, +} diff --git a/bindgen-tests/tests/headers/derive-and-attribute-order.h b/bindgen-tests/tests/headers/derive-and-attribute-order.h new file mode 100644 index 0000000000..6aa8085bbc --- /dev/null +++ b/bindgen-tests/tests/headers/derive-and-attribute-order.h @@ -0,0 +1,7 @@ +// bindgen-flags: --no-layout-tests +// bindgen-parse-callbacks: derive-transparent-serialize=color +typedef struct { + int red; + int green; + int blue; +} color; diff --git a/bindgen-tests/tests/parse_callbacks/mod.rs b/bindgen-tests/tests/parse_callbacks/mod.rs index 7aca0fd1a1..04414ce1d8 100644 --- a/bindgen-tests/tests/parse_callbacks/mod.rs +++ b/bindgen-tests/tests/parse_callbacks/mod.rs @@ -146,6 +146,27 @@ impl ParseCallbacks for WrapAsVariadicFn { } } +#[derive(Debug)] +struct DeriveTransparentSerialize(String); + +impl ParseCallbacks for DeriveTransparentSerialize { + fn add_derives(&self, info: &DeriveInfo<'_>) -> Vec { + if info.name == &self.0 { + vec!["serde::Serialize".to_owned()] + } else { + vec![] + } + } + + fn add_attributes(&self, info: &AttributeInfo<'_>) -> Vec { + if info.name == &self.0 { + vec!["#[serde(transparent)]".to_owned()] + } else { + vec![] + } + } +} + pub fn lookup(cb: &str) -> Box { match cb { "enum-variant-rename" => Box::new(EnumVariantRename), @@ -155,7 +176,11 @@ pub fn lookup(cb: &str) -> Box { "wrap-as-variadic-fn" => Box::new(WrapAsVariadicFn), "type-visibility" => Box::new(TypeVisibility), call_back => { - if let Some(prefix) = + if let Some(name) = + call_back.strip_prefix("derive-transparent-serialize=") + { + Box::new(DeriveTransparentSerialize(name.to_owned())) + } else if let Some(prefix) = call_back.strip_prefix("remove-function-prefix-") { let lnopc = RemovePrefixParseCallback::new(prefix);