use proc_macro::TokenStream;
use quote::quote;
use syn::{ItemFn, parse_macro_input};
pub fn inner_with_com(attr: TokenStream, item: TokenStream) -> TokenStream {
let model = if attr.is_empty() {
quote! { windows::Win32::System::Com::COINIT_APARTMENTTHREADED }
} else {
let lit = parse_macro_input!(attr as syn::LitStr);
let s = lit.value();
match s.to_uppercase().as_str() {
"MTA" | "MULTI" | "MULTITHREADED" => {
quote! { windows::Win32::System::Com::COINIT_MULTITHREADED }
}
"STA" | "APARTMENT" | "APARTMENTTHREADED" => {
quote! { windows::Win32::System::Com::COINIT_APARTMENTTHREADED }
}
_ => {
quote! { windows::Win32::System::Com::COINIT_APARTMENTTHREADED }
}
}
};
let func = parse_macro_input!(item as ItemFn);
let vis = &func.vis;
let sig = &func.sig;
let block = &func.block;
let expanded = quote! {
#vis #sig {
unsafe {
let _ = windows::Win32::System::Com::CoInitializeEx(
None,
#model,
);
}
struct __ComGuard;
impl Drop for __ComGuard {
fn drop(&mut self) {
unsafe { windows::Win32::System::Com::CoUninitialize(); }
}
}
let _com_guard = __ComGuard;
#block
}
};
expanded.into()
}