From 38801967ce06d67a107b7d8aae87618deba348b1 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Mon, 2 Dec 2024 11:04:52 -0500 Subject: [PATCH 1/2] test: check attribute/derive ordering --- Cargo.lock | 21 +++++++++++++++ Cargo.toml | 1 + bindgen-tests/tests/expectations/Cargo.toml | 1 + .../tests/derive-and-attribute-order.rs | 9 +++++++ .../headers/derive-and-attribute-order.h | 7 +++++ bindgen-tests/tests/parse_callbacks/mod.rs | 27 ++++++++++++++++++- 6 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 bindgen-tests/tests/expectations/tests/derive-and-attribute-order.rs create mode 100644 bindgen-tests/tests/headers/derive-and-attribute-order.h diff --git a/Cargo.lock b/Cargo.lock index 142112a213..e3d06d9722 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -550,6 +550,26 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "serde" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "shlex" version = "1.3.0" @@ -620,6 +640,7 @@ dependencies = [ "block", "libloading", "objc", + "serde", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index cd5e4e6223..9494919f67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ quickcheck = "1.0" quote = { version = "1", default-features = false } regex = { version = "1.5.3", default-features = false } rustc-hash = "2.1.0" +serde = { version = "1", features = ["derive"] } shlex = "1" similar = "2.2.1" syn = "2.0" diff --git a/bindgen-tests/tests/expectations/Cargo.toml b/bindgen-tests/tests/expectations/Cargo.toml index 975fd16678..78c91a9c95 100644 --- a/bindgen-tests/tests/expectations/Cargo.toml +++ b/bindgen-tests/tests/expectations/Cargo.toml @@ -15,6 +15,7 @@ edition.workspace = true block.workspace = true libloading.workspace = true objc.workspace = true +serde.workspace = true # Both of these sections need to be copied here from the workspace because # Cargo currently does not allow overriding workspace settings in a member 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..02afb8d203 --- /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(rename_all = "UPPERCASE")] +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..7a71a4f69b --- /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-uppercase-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..b3d3d1b7b3 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(rename_all = \"UPPERCASE\")]".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-uppercase-serialize=") + { + Box::new(DeriveTransparentSerialize(name.to_owned())) + } else if let Some(prefix) = call_back.strip_prefix("remove-function-prefix-") { let lnopc = RemovePrefixParseCallback::new(prefix); From 879cbcbeb8d048941059901468763aeedd107fb3 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Mon, 2 Dec 2024 11:04:52 -0500 Subject: [PATCH 2/2] test: disable formatting on demand --- .../tests/derive-and-attribute-order.rs | 12 +++------ .../headers/derive-and-attribute-order.h | 1 + bindgen-tests/tests/tests.rs | 26 ++++++++++++++----- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/bindgen-tests/tests/expectations/tests/derive-and-attribute-order.rs b/bindgen-tests/tests/expectations/tests/derive-and-attribute-order.rs index 02afb8d203..ecb81f3f93 100644 --- a/bindgen-tests/tests/expectations/tests/derive-and-attribute-order.rs +++ b/bindgen-tests/tests/expectations/tests/derive-and-attribute-order.rs @@ -1,9 +1,5 @@ + #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, serde::Serialize)] -#[serde(rename_all = "UPPERCASE")] -pub struct color { - pub red: ::std::os::raw::c_int, - pub green: ::std::os::raw::c_int, - pub blue: ::std::os::raw::c_int, -} + + +# [repr (C)] # [derive (Debug , Default , Copy , Clone , serde :: Serialize)] # [serde (rename_all = "UPPERCASE")] pub struct color { pub red : :: std :: os :: raw :: c_int , pub green : :: std :: os :: raw :: c_int , pub blue : :: std :: os :: raw :: c_int , } \ No newline at end of file diff --git a/bindgen-tests/tests/headers/derive-and-attribute-order.h b/bindgen-tests/tests/headers/derive-and-attribute-order.h index 7a71a4f69b..f404b3abd1 100644 --- a/bindgen-tests/tests/headers/derive-and-attribute-order.h +++ b/bindgen-tests/tests/headers/derive-and-attribute-order.h @@ -1,5 +1,6 @@ // bindgen-flags: --no-layout-tests // bindgen-parse-callbacks: derive-uppercase-serialize=color +// bindgen-skip-formatting typedef struct { int red; int green; diff --git a/bindgen-tests/tests/tests.rs b/bindgen-tests/tests/tests.rs index 0b3ebe1533..40486eda40 100644 --- a/bindgen-tests/tests/tests.rs +++ b/bindgen-tests/tests/tests.rs @@ -187,17 +187,23 @@ fn compare_generated_header( looked_at, ), }; - + let do_formatting = builder.do_formatting; let (builder, roundtrip_builder) = builder.into_builder(check_roundtrip)?; // We skip the generate() error here so we get a full diff below let actual = match builder.generate() { - Ok(bindings) => format_code(bindings.to_string()).map_err(|err| { - Error::new( - ErrorKind::Other, - format!("Cannot parse the generated bindings: {err}"), - ) - })?, + Ok(bindings) => { + if do_formatting { + format_code(bindings.to_string()).map_err(|err| { + Error::new( + ErrorKind::Other, + format!("Cannot parse the generated bindings: {err}"), + ) + })? + } else { + bindings.to_string() + } + } Err(_) => "/* error generating bindings */\n".into(), }; @@ -237,6 +243,7 @@ fn builder() -> Builder { struct BuilderState { builder: Builder, parse_callbacks: Option, + do_formatting: bool, } impl BuilderState { @@ -255,6 +262,7 @@ impl BuilderState { Some(BuilderState { builder, parse_callbacks: self.parse_callbacks, + do_formatting: self.do_formatting, }) } else { None @@ -273,6 +281,7 @@ fn create_bindgen_builder(header: &Path) -> Result { // Scoop up bindgen-flags from test header let mut flags = Vec::with_capacity(2); let mut parse_callbacks = None; + let mut do_formatting = true; for line in reader.lines() { let line = line?; @@ -298,6 +307,8 @@ fn create_bindgen_builder(header: &Path) -> Result { let parse_cb = line.split("bindgen-parse-callbacks: ").last().unwrap(); parse_callbacks = Some(parse_cb.to_owned()); + } else if line.contains("bindgen-skip-formatting") { + do_formatting = false; } } @@ -345,6 +356,7 @@ fn create_bindgen_builder(header: &Path) -> Result { Ok(BuilderState { builder, parse_callbacks, + do_formatting, }) }