Skip to content

Commit

Permalink
Add ability to prepend code to type generation (#2907)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Mar 1, 2024
1 parent 120d046 commit 1b4833c
Show file tree
Hide file tree
Showing 14 changed files with 116 additions and 13 deletions.
6 changes: 2 additions & 4 deletions crates/libs/bindgen/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ where
Ok(result)
}

// This function is needed to avoid a recursion limit in the Rust compiler.
fn from_string(result: &mut Vec<String>, value: &str) -> Result<()> {
let value = if let Some((value, _)) = value.split_once('#') { value } else { value };

from_iter(result, value.split_whitespace().map(|arg| arg.to_string()))?;
Ok(())
from_iter(result, value.split_whitespace().map(|arg| arg.to_string()))
}

fn from_iter<I, S>(result: &mut Vec<String>, args: I) -> Result<()>
Expand Down
14 changes: 14 additions & 0 deletions crates/libs/bindgen/src/rust/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ pub fn from_reader(reader: &'static metadata::Reader, mut config: std::collectio
return Err(Error::new("cannot combine `implement` and `sys` configuration values"));
}

config.retain(|key, value| {
if let Some(full_name) = key.strip_prefix("prepend:") {
if let Some(index) = full_name.rfind('.') {
let namespace = &full_name[0..index];
let name = &full_name[index + 1..];
if let Some(type_def) = reader.get_type_def(namespace, name).next() {
writer.prepend.insert(type_def, value.to_string());
return false;
}
}
}
true
});

if let Some((key, _)) = config.first_key_value() {
return Err(Error::new(&format!("invalid configuration value `{key}`")));
}
Expand Down
12 changes: 11 additions & 1 deletion crates/libs/bindgen/src/rust/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub struct Writer {
pub minimal: bool, // strips out enumerators - in future possibly other helpers as well
pub no_inner_attributes: bool, // skips the inner attributes at the start of the file
pub vtbl: bool, // include minimal vtbl layout support for interfaces
pub prepend: std::collections::HashMap<metadata::TypeDef, String>,
}

impl Writer {
Expand All @@ -36,6 +37,7 @@ impl Writer {
minimal: false,
no_inner_attributes: false,
vtbl: false,
prepend: Default::default(),
}
}

Expand Down Expand Up @@ -75,12 +77,20 @@ impl Writer {
}
}
pub fn type_def(&self, def: metadata::TypeDef) -> TokenStream {
match def.kind() {
let tokens = match def.kind() {
metadata::TypeKind::Class => classes::writer(self, def),
metadata::TypeKind::Interface => interfaces::writer(self, def),
metadata::TypeKind::Enum => enums::writer(self, def),
metadata::TypeKind::Struct => structs::writer(self, def),
metadata::TypeKind::Delegate => delegates::writer(self, def),
};

if let Some(prepend) = self.prepend.get(&def) {
let mut combined = TokenStream::from(prepend);
combined.combine(&tokens);
combined
} else {
tokens
}
}

Expand Down
3 changes: 3 additions & 0 deletions crates/libs/windows/src/Windows/Win32/Foundation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10490,6 +10490,7 @@ impl ::core::fmt::Debug for WAIT_EVENT {
f.debug_tuple("WAIT_EVENT").field(&self.0).finish()
}
}
#[must_use]
#[repr(transparent)]
#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::marker::Copy, ::core::clone::Clone, ::core::default::Default)]
pub struct WIN32_ERROR(pub u32);
Expand Down Expand Up @@ -10530,6 +10531,7 @@ impl ::core::default::Default for APP_LOCAL_DEVICE_ID {
unsafe { ::core::mem::zeroed() }
}
}
#[must_use]
#[repr(transparent)]
#[derive(::core::cmp::PartialEq, ::core::cmp::Eq)]
pub struct BOOL(pub i32);
Expand Down Expand Up @@ -11161,6 +11163,7 @@ impl ::core::default::Default for LUID {
unsafe { ::core::mem::zeroed() }
}
}
#[must_use]
#[repr(transparent)]
#[derive(::core::cmp::PartialEq, ::core::cmp::Eq)]
pub struct NTSTATUS(pub i32);
Expand Down
1 change: 1 addition & 0 deletions crates/libs/windows/src/Windows/Win32/System/Rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3810,6 +3810,7 @@ impl ::core::fmt::Debug for RPC_NOTIFICATION_TYPES {
f.debug_tuple("RPC_NOTIFICATION_TYPES").field(&self.0).finish()
}
}
#[must_use]
#[repr(transparent)]
#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::marker::Copy, ::core::clone::Clone, ::core::default::Default)]
pub struct RPC_STATUS(pub i32);
Expand Down
2 changes: 1 addition & 1 deletion crates/samples/windows/create_window/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ extern "system" fn wndproc(window: HWND, message: u32, wparam: WPARAM, lparam: L
match message {
WM_PAINT => {
println!("WM_PAINT");
ValidateRect(window, None);
_ = ValidateRect(window, None);
LRESULT(0)
}
WM_DESTROY => {
Expand Down
4 changes: 2 additions & 2 deletions crates/samples/windows/direct2d/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ impl Window {
let mut ps = PAINTSTRUCT::default();
BeginPaint(self.handle, &mut ps);
self.render().unwrap();
EndPaint(self.handle, &ps);
_ = EndPaint(self.handle, &ps);
LRESULT(0)
}
WM_SIZE => {
Expand Down Expand Up @@ -425,7 +425,7 @@ impl Window {
DispatchMessageA(&message);
}
} else {
GetMessageA(&mut message, None, 0, 0);
_ = GetMessageA(&mut message, None, 0, 0);

if message.message == WM_QUIT {
return Ok(());
Expand Down
4 changes: 2 additions & 2 deletions crates/samples/windows/direct3d12/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,14 @@ where
};

sample.bind_to_window(&hwnd)?;
unsafe { ShowWindow(hwnd, SW_SHOW) };
unsafe { _ = ShowWindow(hwnd, SW_SHOW) };

loop {
let mut message = MSG::default();

if unsafe { PeekMessageA(&mut message, None, 0, 0, PM_REMOVE) }.into() {
unsafe {
TranslateMessage(&message);
_ = TranslateMessage(&message);
DispatchMessageA(&message);
}

Expand Down
2 changes: 1 addition & 1 deletion crates/tests/lib/tests/win.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fn linker() -> Result<()> {
#[test]
fn gdi() {
unsafe {
AlphaBlend(
_ = AlphaBlend(
HDC::default(),
0,
0,
Expand Down
10 changes: 10 additions & 0 deletions crates/tests/standalone/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,16 @@ fn main() {
"src/b_vtbl_4.rs",
&["Windows.Win32.System.Com.IPersistFile"],
);

riddle(
"src/b_prepend.rs",
&["Windows.Foundation.DateTime"],
&[
"flatten",
"minimal",
"prepend:Windows.Foundation.DateTime=#[derive(std::cmp::PartialOrd,std::cmp::Ord)]",
],
);
}

fn write_sys(output: &str, filter: &[&str]) {
Expand Down
45 changes: 45 additions & 0 deletions crates/tests/standalone/src/b_prepend.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Bindings generated by `windows-bindgen` 0.54.0

#![allow(
non_snake_case,
non_upper_case_globals,
non_camel_case_types,
dead_code,
clippy::all
)]
#[derive(std::cmp::PartialOrd, std::cmp::Ord)]
#[repr(C)]
pub struct DateTime {
pub UniversalTime: i64,
}
impl ::core::marker::Copy for DateTime {}
impl ::core::clone::Clone for DateTime {
fn clone(&self) -> Self {
*self
}
}
impl ::core::fmt::Debug for DateTime {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.debug_struct("DateTime")
.field("UniversalTime", &self.UniversalTime)
.finish()
}
}
impl ::windows_core::TypeKind for DateTime {
type TypeKind = ::windows_core::CopyType;
}
impl ::windows_core::RuntimeType for DateTime {
const SIGNATURE: ::windows_core::imp::ConstBuffer =
::windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Foundation.DateTime;i8)");
}
impl ::core::cmp::PartialEq for DateTime {
fn eq(&self, other: &Self) -> bool {
self.UniversalTime == other.UniversalTime
}
}
impl ::core::cmp::Eq for DateTime {}
impl ::core::default::Default for DateTime {
fn default() -> Self {
unsafe { ::core::mem::zeroed() }
}
}
18 changes: 18 additions & 0 deletions crates/tests/standalone/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod b_none;
mod b_overloads;
mod b_pcstr;
mod b_pcwstr;
mod b_prepend;
mod b_pstr;
mod b_pwstr;
mod b_std;
Expand Down Expand Up @@ -184,3 +185,20 @@ fn from_included() {
included::GetVersion();
}
}

#[test]
fn prepend() {
use b_prepend::*;
let mut dates = [
DateTime { UniversalTime: 123 },
DateTime { UniversalTime: 42 },
];
dates.sort();
assert_eq!(
&dates,
&[
DateTime { UniversalTime: 42 },
DateTime { UniversalTime: 123 }
]
);
}
4 changes: 2 additions & 2 deletions crates/tests/win32/tests/win32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ fn com_inheritance() {
assert!(factory.IsCurrent().as_bool());

// IDXGIFactory2
factory.IsWindowedStereoEnabled();
_ = factory.IsWindowedStereoEnabled();

// IDXGIFactory3
assert!(factory.GetCreationFlags() == 0);
Expand All @@ -202,7 +202,7 @@ fn com_inheritance() {
#[test]
fn onecore_imports() -> windows::core::Result<()> {
unsafe {
HasExpandedResources()?;
_ = HasExpandedResources()?;

let uri = CreateUri(w!("http://kennykerr.ca"), URI_CREATE_FLAGS::default(), 0)?;

Expand Down
4 changes: 4 additions & 0 deletions crates/tools/windows/bindings.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
--in crates/libs/bindgen/default
--out crates/libs/windows/src/lib.rs
--config package
--config prepend:Windows.Win32.Foundation.WIN32_ERROR=#[must_use]
--config prepend:Windows.Win32.Foundation.BOOL=#[must_use]
--config prepend:Windows.Win32.Foundation.NTSTATUS=#[must_use]
--config prepend:Windows.Win32.System.Rpc.RPC_STATUS=#[must_use]

--filter
Windows
Expand Down

0 comments on commit 1b4833c

Please sign in to comment.