Skip to content

Commit

Permalink
Add natural error translation for RPC (#2883)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Feb 27, 2024
1 parent 2c2d784 commit 3807aba
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 1 deletion.
1 change: 1 addition & 0 deletions crates/libs/bindgen/src/rust/extensions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub fn gen_mod(writer: &Writer, namespace: &str) -> TokenStream {
"Windows.Foundation" => concat!(include_str!("mod/Foundation/TimeSpan.rs"),),
"Windows.Win32.Foundation" => concat!(include_str!("mod/Win32/Foundation/BOOL.rs"), include_str!("mod/Win32/Foundation/BOOLEAN.rs"), include_str!("mod/Win32/Foundation/NTSTATUS.rs"), include_str!("mod/Win32/Foundation/VARIANT_BOOL.rs"), include_str!("mod/Win32/Foundation/WIN32_ERROR.rs"),),
"Windows.Win32.Networking.WinSock" => concat!(include_str!("mod/Win32/Networking/WinSock/IN_ADDR.rs"), include_str!("mod/Win32/Networking/WinSock/IN6_ADDR.rs"), include_str!("mod/Win32/Networking/WinSock/SOCKADDR_IN.rs"), include_str!("mod/Win32/Networking/WinSock/SOCKADDR_IN6.rs"), include_str!("mod/Win32/Networking/WinSock/SOCKADDR_INET.rs"),),
"Windows.Win32.System.Rpc" => include_str!("mod/Win32/System/Rpc/RPC_STATUS.rs"),
"Windows.Win32.UI.WindowsAndMessaging" => {
include_str!("mod/Win32/UI/WindowsAndMessaging/WindowLong.rs")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
impl RPC_STATUS {
#[inline]
pub const fn is_ok(self) -> bool {
self.0 == 0
}
#[inline]
pub const fn is_err(self) -> bool {
!self.is_ok()
}
#[inline]
pub const fn to_hresult(self) -> ::windows_core::HRESULT {
::windows_core::HRESULT::from_win32(self.0 as u32)
}
#[inline]
pub fn ok(self) -> ::windows_core::Result<()> {
if self.is_ok() {
Ok(())
} else {
Err(self.to_hresult().into())
}
}
}
impl ::core::convert::From<RPC_STATUS> for ::windows_core::HRESULT {
fn from(value: RPC_STATUS) -> Self {
value.to_hresult()
}
}
impl ::core::convert::From<RPC_STATUS> for ::windows_core::Error {
fn from(value: RPC_STATUS) -> Self {
value.to_hresult().into()
}
}
1 change: 1 addition & 0 deletions crates/libs/metadata/src/type_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ impl TypeName {
pub const BOOL: Self = Self::from_const("Windows.Win32.Foundation", "BOOL");
pub const WIN32_ERROR: Self = Self::from_const("Windows.Win32.Foundation", "WIN32_ERROR");
pub const NTSTATUS: Self = Self::from_const("Windows.Win32.Foundation", "NTSTATUS");
pub const RPC_STATUS: Self = Self::from_const("Windows.Win32.System.Rpc", "RPC_STATUS");

pub const D2D_MATRIX_3X2_F: Self = Self::from_const("Windows.Win32.Graphics.Direct2D.Common", "D2D_MATRIX_3X2_F");
pub const D3DMATRIX: Self = Self::from_const("Windows.Win32.Graphics.Direct3D", "D3DMATRIX");
Expand Down
32 changes: 32 additions & 0 deletions crates/libs/windows/src/Windows/Win32/System/Rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9830,3 +9830,35 @@ pub type USER_MARSHAL_SIZING_ROUTINE = ::core::option::Option<unsafe extern "sys
pub type USER_MARSHAL_UNMARSHALLING_ROUTINE = ::core::option::Option<unsafe extern "system" fn(param0: *mut u32, param1: *mut u8, param2: *mut ::core::ffi::c_void) -> *mut u8>;
#[cfg(feature = "Win32_System_Com")]
pub type XMIT_HELPER_ROUTINE = ::core::option::Option<unsafe extern "system" fn(param0: *mut MIDL_STUB_MESSAGE)>;
impl RPC_STATUS {
#[inline]
pub const fn is_ok(self) -> bool {
self.0 == 0
}
#[inline]
pub const fn is_err(self) -> bool {
!self.is_ok()
}
#[inline]
pub const fn to_hresult(self) -> ::windows_core::HRESULT {
::windows_core::HRESULT::from_win32(self.0 as u32)
}
#[inline]
pub fn ok(self) -> ::windows_core::Result<()> {
if self.is_ok() {
Ok(())
} else {
Err(self.to_hresult().into())
}
}
}
impl ::core::convert::From<RPC_STATUS> for ::windows_core::HRESULT {
fn from(value: RPC_STATUS) -> Self {
value.to_hresult()
}
}
impl ::core::convert::From<RPC_STATUS> for ::windows_core::Error {
fn from(value: RPC_STATUS) -> Self {
value.to_hresult().into()
}
}
1 change: 1 addition & 0 deletions crates/tests/error/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ features = [
"implement",
"Foundation",
"Win32_Foundation",
"Win32_System_Rpc",
]

[dev-dependencies]
Expand Down
39 changes: 38 additions & 1 deletion crates/tests/error/tests/test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use windows::{core::*, Win32::Foundation::*};
use windows::{core::*, Win32::Foundation::*, Win32::System::Rpc::*};

#[test]
fn hresult() -> Result<()> {
Expand Down Expand Up @@ -57,3 +57,40 @@ fn ntstatus() -> Result<()> {

STATUS_SUCCESS.ok()
}

#[test]
fn rpc() -> Result<()> {
helpers::set_thread_ui_language();

let _: RPC_STATUS = RPC_S_OK;
assert!(RPC_S_OK.is_ok());
assert!(!RPC_S_OK.is_err());

let r: Result<()> = RPC_S_OK.ok();
assert!(r.is_ok());

assert_eq!(RPC_S_OK.to_hresult(), HRESULT(0));
let hr: HRESULT = RPC_S_OK.into();
assert_eq!(hr, HRESULT(0));

let _: RPC_STATUS = RPC_S_NOT_LISTENING;
assert!(!RPC_S_NOT_LISTENING.is_ok());
assert!(RPC_S_NOT_LISTENING.is_err());

let r: Result<()> = RPC_S_NOT_LISTENING.ok();
assert!(r.is_err());

assert_eq!(RPC_S_NOT_LISTENING.to_hresult(), HRESULT::from_win32(1715));
let hr: HRESULT = RPC_S_NOT_LISTENING.into();
assert_eq!(hr, HRESULT::from_win32(1715));

let e: Error = RPC_S_NOT_LISTENING.into();
assert_eq!(r.unwrap_err(), e);
assert_eq!(e.code(), HRESULT::from_win32(1715));
assert_eq!(e.message(), "The RPC server is not listening.");

let r: Result<()> = unsafe { RpcServerListen(0, 0, 1).ok() };
assert_eq!(r.unwrap_err().code(), RPC_S_MAX_CALLS_TOO_SMALL.into());

RPC_S_OK.ok()
}

0 comments on commit 3807aba

Please sign in to comment.