com_macros_support/class/
class_factory.rs1use super::Class;
2use proc_macro2::TokenStream;
3use quote::quote;
4
5pub fn generate(class: &Class) -> TokenStream {
6 if !class.has_class_factory {
7 return TokenStream::new();
8 }
9
10 let class_factory_ident = crate::utils::class_factory_ident(&class.name);
11 let class_name = &class.name;
12 let user_fields = class.fields.iter().map(|f| {
13 let ty = &f.ty;
14 quote! { <#ty as ::core::default::Default>::default() }
15 });
16 quote! {
17 ::com::class! {
18 #[no_class_factory]
19 pub class #class_factory_ident: ::com::interfaces::IClassFactory {}
20
21 impl ::com::interfaces::IClassFactory for #class_factory_ident {
22 unsafe fn CreateInstance(
23 &self,
24 aggr: *mut ::core::ptr::NonNull<<::com::interfaces::IUnknown as ::com::Interface>::VTable>,
25 riid: *const ::com::sys::IID,
26 ppv: *mut *mut ::core::ffi::c_void,
27 ) -> ::com::sys::HRESULT {
28 assert!(!riid.is_null(), "iid passed to CreateInstance was null");
29 if !aggr.is_null() {
30 return ::com::sys::CLASS_E_NOAGGREGATION;
31 }
32
33 let instance = #class_name::allocate(#(#user_fields),*);
34 instance.QueryInterface(riid, ppv)
35 }
36
37 unsafe fn LockServer(&self, _increment: com::sys::BOOL) -> com::sys::HRESULT {
38 ::com::sys::S_OK
39 }
40 }
41 }
42 }
43}