summaryrefslogtreecommitdiffstats
path: root/vendor/windows-bindgen/src/interfaces.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/windows-bindgen/src/interfaces.rs')
-rw-r--r--vendor/windows-bindgen/src/interfaces.rs224
1 files changed, 224 insertions, 0 deletions
diff --git a/vendor/windows-bindgen/src/interfaces.rs b/vendor/windows-bindgen/src/interfaces.rs
new file mode 100644
index 000000000..1643e7798
--- /dev/null
+++ b/vendor/windows-bindgen/src/interfaces.rs
@@ -0,0 +1,224 @@
+use super::*;
+
+pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
+ if gen.sys {
+ gen_sys_interface(gen, def)
+ } else {
+ gen_win_interface(gen, def)
+ }
+}
+
+fn gen_sys_interface(gen: &Gen, def: TypeDef) -> TokenStream {
+ let name = gen.reader.type_def_name(def);
+ let ident = to_ident(name);
+
+ if gen.reader.type_def_is_exclusive(def) {
+ quote! {}
+ } else {
+ quote! {
+ pub type #ident = *mut ::core::ffi::c_void;
+ }
+ }
+}
+
+fn gen_win_interface(gen: &Gen, def: TypeDef) -> TokenStream {
+ let generics: &Vec<Type> = &gen.reader.type_def_generics(def).collect();
+ let ident = gen.type_def_name(def, generics);
+ let is_exclusive = gen.reader.type_def_is_exclusive(def);
+ let phantoms = gen.generic_phantoms(generics);
+ let constraints = gen.generic_constraints(generics);
+ let cfg = gen.reader.type_def_cfg(def, &[]);
+ let doc = gen.cfg_doc(&cfg);
+ let features = gen.cfg_features(&cfg);
+ let interfaces = gen
+ .reader
+ .type_interfaces(&Type::TypeDef((def, generics.to_vec())));
+ let vtables = gen.reader.type_def_vtables(def);
+ let has_unknown_base = matches!(vtables.first(), Some(Type::IUnknown));
+
+ let mut tokens = if is_exclusive {
+ quote! { #[doc(hidden)] }
+ } else {
+ quote! { #doc }
+ };
+
+ if has_unknown_base {
+ tokens.combine(&quote! {
+ #features
+ #[repr(transparent)]
+ pub struct #ident(::windows::core::IUnknown, #phantoms) where #constraints;
+ });
+ } else {
+ tokens.combine(&quote! {
+ #features
+ #[repr(transparent)]
+ pub struct #ident(::std::ptr::NonNull<::std::ffi::c_void>);
+ });
+ }
+
+ if !is_exclusive {
+ let mut methods = quote! {};
+ // We need to distinguish between public and virtual methods because some WinRT type hierarchies inherit colliding (overloaded)
+ // methods that must be distinguishable.
+ let method_names = &mut MethodNames::new();
+ let virtual_names = &mut MethodNames::new();
+
+ if gen
+ .reader
+ .type_def_flags(def)
+ .contains(TypeAttributes::WINRT)
+ {
+ for method in gen.reader.type_def_methods(def) {
+ methods.combine(&winrt_methods::gen(
+ gen,
+ def,
+ generics,
+ InterfaceKind::Default,
+ method,
+ method_names,
+ virtual_names,
+ ));
+ }
+ for interface in &interfaces {
+ if let Type::TypeDef((def, generics)) = &interface.ty {
+ for method in gen.reader.type_def_methods(*def) {
+ methods.combine(&winrt_methods::gen(
+ gen,
+ *def,
+ generics,
+ InterfaceKind::None,
+ method,
+ method_names,
+ virtual_names,
+ ));
+ }
+ }
+ }
+ } else {
+ let mut bases = vtables.len();
+ for ty in &vtables {
+ match ty {
+ Type::IUnknown | Type::IInspectable => {}
+ Type::TypeDef((def, _)) => {
+ let kind = if gen.reader.type_def_type_name(*def) == TypeName::IDispatch {
+ InterfaceKind::None
+ } else {
+ InterfaceKind::Default
+ };
+ for method in gen.reader.type_def_methods(*def) {
+ methods.combine(&com_methods::gen(
+ gen,
+ *def,
+ kind,
+ method,
+ method_names,
+ virtual_names,
+ bases,
+ ));
+ }
+ }
+ _ => unimplemented!(),
+ }
+
+ bases -= 1;
+ }
+ for method in gen.reader.type_def_methods(def) {
+ methods.combine(&com_methods::gen(
+ gen,
+ def,
+ InterfaceKind::Default,
+ method,
+ method_names,
+ virtual_names,
+ 0,
+ ));
+ }
+ }
+
+ tokens.combine(&quote! {
+ #features
+ impl<#constraints> #ident {
+ #methods
+ }
+ });
+
+ if !vtables.is_empty() && generics.is_empty() {
+ let mut hierarchy = format!("::windows::imp::interface_hierarchy!({ident}");
+ let mut hierarchy_cfg = cfg.clone();
+
+ for ty in &vtables {
+ let into = gen.type_name(ty);
+
+ write!(&mut hierarchy, ", {into}").unwrap();
+ hierarchy_cfg = hierarchy_cfg.union(&gen.reader.type_cfg(ty));
+ }
+
+ hierarchy.push_str(");");
+ tokens.combine(&gen.cfg_features(&hierarchy_cfg));
+ tokens.push_str(&hierarchy);
+ } else {
+ for ty in &vtables {
+ let into = gen.type_name(ty);
+ let cfg = gen.cfg_features(&cfg.union(&gen.reader.type_cfg(ty)));
+ tokens.combine(&quote! {
+ #cfg
+ impl<#constraints> windows::core::CanInto<#into> for #ident {}
+ });
+ }
+ }
+
+ if gen
+ .reader
+ .type_def_flags(def)
+ .contains(TypeAttributes::WINRT)
+ {
+ for interface in &interfaces {
+ let into = gen.type_name(&interface.ty);
+ let cfg = gen.cfg_features(&cfg.union(&gen.reader.type_cfg(&interface.ty)));
+ tokens.combine(&quote! {
+ #cfg
+ impl<#constraints> windows::core::CanTryInto<#into> for #ident {}
+ });
+ }
+ }
+
+ tokens.combine(&gen.interface_core_traits(
+ def,
+ generics,
+ &ident,
+ &constraints,
+ &phantoms,
+ &features,
+ ));
+ tokens.combine(&gen.interface_winrt_trait(
+ def,
+ generics,
+ &ident,
+ &constraints,
+ &phantoms,
+ &features,
+ ));
+ tokens.combine(&gen.async_get(def, generics, &ident, &constraints, &phantoms, &features));
+ tokens.combine(&iterators::gen(
+ gen,
+ def,
+ generics,
+ &ident,
+ &constraints,
+ &phantoms,
+ &cfg,
+ ));
+ tokens.combine(&gen.agile(def, &ident, &constraints, &features));
+ }
+
+ tokens.combine(&gen.interface_trait(
+ def,
+ generics,
+ &ident,
+ &constraints,
+ &features,
+ has_unknown_base,
+ ));
+ tokens.combine(&gen.interface_vtbl(def, generics, &ident, &constraints, &features));
+ tokens
+}