use windows::Win32::System::Com::{COINIT_MULTITHREADED, CoUninitialize};
use windows::core::Result;
use callcomapi_macros::with_com;
mod common;
#[link(name = "ole32")]
unsafe extern "system" {
fn CoInitializeEx(
pvreserved: *const core::ffi::c_void,
dwcoinit: windows::Win32::System::Com::COINIT,
) -> windows::core::HRESULT;
}
fn check_com() -> Result<()> {
use windows::Win32::Foundation::S_OK;
let hr = unsafe { CoInitializeEx(core::ptr::null(), COINIT_MULTITHREADED) };
if hr != S_OK {
return Err(windows::core::Error::from(hr));
}
unsafe { CoUninitialize() };
Ok(())
}
#[with_com]
fn foo() -> i32 {
common::call_com_api().unwrap();
42
}
#[test]
fn test_macro_wraps_function() {
assert_eq!(foo(), 42);
}
#[with_com("STA")]
fn sta_foo() -> i32 {
common::call_com_api().unwrap();
99
}
#[test]
fn test_sta_model() {
assert_eq!(sta_foo(), 99);
}
#[with_com]
fn generic<T>(x: T) -> T {
x
}
#[test]
fn test_generic() {
assert_eq!(generic(10u8), 10);
}
#[with_com]
async fn async_fn() -> i32 {
common::call_com_api().unwrap();
7
}
#[test]
fn test_async() {
let val = futures::executor::block_on(async_fn());
assert_eq!(val, 7);
}
#[tokio::test]
async fn test_async_await() {
let val = async_fn().await;
assert_eq!(val, 7);
}
#[with_com]
fn will_panic() {
panic!("oops");
}
#[test]
fn test_panic_safety() {
let _ = std::panic::catch_unwind(|| will_panic());
check_com().unwrap();
}