fn rust_to_com_delegate(
    itf: &model::ComInterface,
    itf_variant: &model::ComInterfaceVariant,
    method_info: &ComMethodInfo,
) -> TokenStream
{
    // The COM out-arguments that mirror the Rust return value will
    // require temporary variables during the COM call. Format their
    // declarations.
    let infallible = method_info.returnhandler.is_infallible();
    let out_arg_declarations = method_info
        .returnhandler
        .com_out_args()
        .iter()
        .map(|ca| {
            let ident = &ca.name;
            let ty = &ca.handler.com_ty(ca.span);
            let default = ca.handler.default_value();
            quote_spanned!(ca.span => let mut #ident : #ty = #default; )
        })
        .collect::<Vec<_>>();

    // Format the in and out parameters for the COM call.
    let params: Vec<_> = method_info
        .raw_com_args()
        .into_iter()
        .map(|com_arg| {
            let name = com_arg.name;
            match com_arg.dir {
                Direction::In => {
                    com_arg
                        .handler
                        .rust_to_com(&name, com_arg.span, Direction::In, infallible)
                }
                Direction::Out | Direction::Retval => quote_spanned!(com_arg.span => &mut #name ),
            }
        })
        .collect();

    // Combine the parameters into the final parameter list.
    // This includes the 'this' pointer and both the IN and OUT
    // parameters.
    let params =
        iter::once(quote_spanned!(method_info.rust_self_arg.span() => comptr.ptr.as_ptr()))
            .chain(params);

    // Create the return statement.
    let return_ident = Ident::new("__result", Span::call_site());
    let return_statement = method_info.returnhandler.com_to_rust_return(&return_ident);

    // Resolve some of the fields needed for quote.
    let method_ident = &method_info.name;
    let return_ty = &method_info.rust_return_ty;
    let iid_tokens = utils::get_guid_tokens(&itf_variant.iid, method_info.signature_span);
    let itf_ref = &itf.itf_ref;
    let ts_type = itf_variant.type_system.as_typesystem_type(itf.span);

    // Construct the final method.
    if infallible {
        quote_spanned!(method_info.signature_span =>
            #[allow(unused_imports)]
            let vtbl = comptr.ptr.as_ptr() as *const *const <#itf_ref as
                intercom::attributes::ComInterfaceVariant<#ts_type>>::VTable;

            #[allow(unused_unsafe)]  // The fn itself _might_ be unsafe.
            unsafe {
                #( #out_arg_declarations )*
                let #return_ident = ((**vtbl).#method_ident)( #( #params ),* );

                let __intercom_iid = #iid_tokens;
                #[allow(unused_braces)]
                return { #return_statement };
            }
        )
    } else {
        quote_spanned!(method_info.signature_span =>
            #[allow(unused_imports)]
            let vtbl = comptr.ptr.as_ptr() as *const *const <#itf_ref as
                intercom::attributes::ComInterfaceVariant<#ts_type>>::VTable;

            // Use an IIFE to act as a try/catch block. The various template
            // substitutions might end up using ?'s for error handling. The IIFE allows
            // us to handle the results here immediately.
            #[allow(unused_unsafe)]  // The fn itself _might_ be unsafe.
            let __intercom_result : Result< #return_ty, intercom::ComError > = ( || unsafe {
                #( #out_arg_declarations )*
                let #return_ident = ((**vtbl).#method_ident)( #( #params ),* );

                let __intercom_iid = #iid_tokens;
                #[allow(unused_braces)]
                Ok( { #return_statement } )
            } )();

            return match __intercom_result {
                Ok( v ) => v,
                Err( err ) => < #return_ty as intercom::ErrorValue >::from_error( err ),
            };
        )
    }
}
/// Creates the functions responsible for delegating calls from Rust to COM
/// interfaces.
///
/// # Arguments
///
/// * `itf` - Interface details.
/// * `itf_variant` - Interface variant details.
/// * `method_info` - Method to delegate.
Creates the functions responsible for delegating calls from Rust to COM
interfaces.
Creates the functions responsible for delegating calls from Rust to COM interfaces .
fn rust_to_com_delegate(
    itf: &model::ComInterface,
    itf_variant: &model::ComInterfaceVariant,
    method_info: &ComMethodInfo,
) -> TokenStream
{
    // The COM out-arguments that mirror the Rust return value will
    // require temporary variables during the COM call. Format their
    // declarations.
    let infallible = method_info.returnhandler.is_infallible();
    let out_arg_declarations = method_info
        .returnhandler
        .com_out_args()
        .iter()
        .map(|ca| {
            let ident = &ca.name;
            let ty = &ca.handler.com_ty(ca.span);
            let default = ca.handler.default_value();
            quote_spanned!(ca.span => let mut #ident : #ty = #default; )
        })
        .collect::<Vec<_>>();
    // Format the in and out parameters for the COM call.
    let params: Vec<_> = method_info
        .raw_com_args()
        .into_iter()
        .map(|com_arg| {
            let name = com_arg.name;
            match com_arg.dir {
                Direction::In => {
                    com_arg
                        .handler
                        .rust_to_com(&name, com_arg.span, Direction::In, infallible)
                }
                Direction::Out | Direction::Retval => quote_spanned!(com_arg.span => &mut #name ),
            }
        })
        .collect();
    // Combine the parameters into the final parameter list.
    // This includes the 'this' pointer and both the IN and OUT
    // parameters.
    let params =
        iter::once(quote_spanned!(method_info.rust_self_arg.span() => comptr.ptr.as_ptr()))
            .chain(params);
    // Create the return statement.
    let return_ident = Ident::new("__result", Span::call_site());
    let return_statement = method_info.returnhandler.com_to_rust_return(&return_ident);
    // Resolve some of the fields needed for quote.
    let method_ident = &method_info.name;
    let return_ty = &method_info.rust_return_ty;
    let iid_tokens = utils::get_guid_tokens(&itf_variant.iid, method_info.signature_span);
    let itf_ref = &itf.itf_ref;
    let ts_type = itf_variant.type_system.as_typesystem_type(itf.span);
    // Construct the final method.
    if infallible {
        quote_spanned!(method_info.signature_span =>
            #[allow(unused_imports)]
            let vtbl = comptr.ptr.as_ptr() as *const *const <#itf_ref as
                intercom::attributes::ComInterfaceVariant<#ts_type>>::VTable;
            #[allow(unused_unsafe)]  // The fn itself _might_ be unsafe.
            unsafe {
                #( #out_arg_declarations )*
                let #return_ident = ((**vtbl).#method_ident)( #( #params ),* );
                let __intercom_iid = #iid_tokens;
                #[allow(unused_braces)]
                return { #return_statement };
            }
        )
    } else {
        quote_spanned!(method_info.signature_span =>
            #[allow(unused_imports)]
            let vtbl = comptr.ptr.as_ptr() as *const *const <#itf_ref as
                intercom::attributes::ComInterfaceVariant<#ts_type>>::VTable;
            // Use an IIFE to act as a try/catch block. The various template
            // substitutions might end up using ?'s for error handling. The IIFE allows
            // us to handle the results here immediately.
            #[allow(unused_unsafe)]  // The fn itself _might_ be unsafe.
            let __intercom_result : Result< #return_ty, intercom::ComError > = ( || unsafe {
                #( #out_arg_declarations )*
                let #return_ident = ((**vtbl).#method_ident)( #( #params ),* );
                let __intercom_iid = #iid_tokens;
                #[allow(unused_braces)]
                Ok( { #return_statement } )
            } )();
            return match __intercom_result {
                Ok( v ) => v,
                Err( err ) => < #return_ty as intercom::ErrorValue >::from_error( err ),
            };
        )
    }
}
fn rust_to_com_delegate ( itf : & model :: ComInterface , itf_variant : & model :: ComInterfaceVariant , method_info : & ComMethodInfo , ) -> TokenStream { // The COM out-arguments that mirror the Rust return value will // require temporary variables during the COM call. Format their // declarations. let infallible = method_info . returnhandler . is_infallible ( ) ; let out_arg_declarations = method_info . returnhandler . com_out_args ( ) . iter ( ) . map ( | ca | { let ident = & ca . name ; let ty = & ca . handler . com_ty ( ca . span ) ; let default = ca . handler . default_value ( ) ; quote_spanned ! ( ca span let mut ident ty default ) } ) . collect :: < Vec < _ > > ( ) ; // Format the in and out parameters for the COM call. let params : Vec < _ > = method_info . raw_com_args ( ) . into_iter ( ) . map ( | com_arg | { let name = com_arg . name ; match com_arg . dir { Direction :: In => { com_arg . handler . rust_to_com ( & name , com_arg . span , Direction :: In , infallible ) } Direction :: Out | Direction :: Retval => quote_spanned ! ( com_arg span mut name ) , } } ) . collect ( ) ; // Combine the parameters into the final parameter list. // This includes the 'this' pointer and both the IN and OUT // parameters. let params = iter :: once ( quote_spanned ! ( method_info rust_self_arg span ( ) comptr ptr as_ptr ( ) ) ) . chain ( params ) ; // Create the return statement. let return_ident = Ident :: new ( " " , Span :: call_site ( ) ) ; let return_statement = method_info . returnhandler . com_to_rust_return ( & return_ident ) ; // Resolve some of the fields needed for quote. let method_ident = & method_info . name ; let return_ty = & method_info . rust_return_ty ; let iid_tokens = utils :: get_guid_tokens ( & itf_variant . iid , method_info . signature_span ) ; let itf_ref = & itf . itf_ref ; let ts_type = itf_variant . type_system . as_typesystem_type ( itf . span ) ; // Construct the final method. if infallible { quote_spanned ! ( method_info signature_span [ allow ( unused_imports ) ] let vtbl comptr ptr as_ptr ( ) as const const itf_ref as intercom attributes ComInterfaceVariant ts_type VTable [ allow ( unused_unsafe ) ] // The fn itself _might_ be unsafe. unsafe { ( out_arg_declarations ) let return_ident ( ( vtbl ) method_ident ) ( ( params ) ) let __intercom_iid iid_tokens [ allow ( unused_braces ) ] return { return_statement } } ) } else { quote_spanned ! ( method_info signature_span [ allow ( unused_imports ) ] let vtbl comptr ptr as_ptr ( ) as const const itf_ref as intercom attributes ComInterfaceVariant ts_type VTable // Use an IIFE to act as a try/catch block. The various template // substitutions might end up using ?'s for error handling. The IIFE allows // us to handle the results here immediately. [ allow ( unused_unsafe ) ] // The fn itself _might_ be unsafe. let __intercom_result Result return_ty intercom ComError ( unsafe { ( out_arg_declarations ) let return_ident ( ( vtbl ) method_ident ) ( ( params ) ) let __intercom_iid iid_tokens [ allow ( unused_braces ) ] Ok ( { return_statement } ) } ) ( ) return match __intercom_result { Ok ( v ) v Err ( err ) return_ty as intercom ErrorValue from_error ( err ) } ) } }
Creates the functions responsible for delegating calls from Rust to COM
interfaces.
Creates the functions responsible for delegating calls from Rust to COM interfaces .
itf
&model::ComInterface
itf_variant
&model::ComInterfaceVariant
method_info
&ComMethodInfo
itf
&model::ComInterface
itf_variant
&model::ComInterfaceVariant
method_info
&ComMethodInfo