pub fn from_ast(
        crate_name : &str,
        attr : TokenStream,
        item : &::syn::Item,
    ) -> ParseResult< ComInterface >
    {
        let attr : ComInterfaceAttr = ::syn::parse2( attr )
            .map_err( |_| ParseError::ComInterface(
                    item.get_ident().unwrap().to_string(),
                    "Attribute syntax error".into() ) )?;

        // Get the interface details. As [com_interface] can be applied to both
        // impls and traits this handles both of those.
        let ( itf_ident, fns, itf_type, unsafety ) =
                ::utils::get_ident_and_fns( item )
                    .ok_or_else( || ParseError::ComInterface(
                            item.get_ident().unwrap().to_string(),
                            "Unsupported associated item".into() ) )?;

        // The second argument is the optional base class. If there's no base
        // class defined, use IUnknown as the default. The value of NO_BASE will
        // construct an interface that has no base class.
        //
        // In practice the NO_BASE should be used ONLY for the IUnknown itself.
        let base = attr.base()
                .map_err( |msg| ParseError::ComInterface(
                    item.get_ident().unwrap().to_string(), msg ) )?;
        let base = match base {
            Some( b ) => if b == "NO_BASE" { None } else { Some( b.to_owned() ) },
            None => Some( Ident::new( "IUnknown", Span::call_site() ) ),
        };

        // Visibility for trait interfaces is the visibility of the trait.
        //
        // For implicit interfaces (impl Struct) the visibility is always public.
        // These interfaces should only exist for COM types that are meant to be
        // called from external sources as they can't be impl'd for random ComItf.
        //
        // Note this may conflict with visibility of the actual [com_class], but
        // nothing we can do for this really.
        let visibility = if let ::syn::Item::Trait( ref t ) = *item {
                    t.vis.clone()
                } else {
                    parse_quote!( pub )
                };

        let variants = OrderMap::from_iter(
            [ ModelTypeSystem::Automation, ModelTypeSystem::Raw ].iter().map( |&ts| {

            let itf_unique_ident = Ident::new(
                    &format!( "{}_{:?}", itf_ident.to_string(), ts ), Span::call_site() );

                // IUnknown interfaces do not have type system variants.
                let unique_base = match base {
                    Some( ref iunk ) if iunk == "IUnknown" => base.clone(),
                    ref b => b.as_ref().map( |b| Ident::new( &format!( "{}_{:?}", b, ts ), Span::call_site() ) )
                };

                let iid_attr = attr.iid( ts )
                        .map_err( |msg| ParseError::ComInterface(
                            item.get_ident().unwrap().to_string(), msg ) )?;
                let iid = match iid_attr {
                    Some( iid ) => GUID::parse( &iid.value() )
                        .map_err( |_| ParseError::ComInterface(
                                item.get_ident().unwrap().to_string(),
                                "Bad IID format".into() ) )?,
                    None => ::utils::generate_iid(
                            crate_name, &itf_unique_ident.to_string(), ts )
                };

                // Read the method details.
                //
                // TODO: Currently we ignore invalid methods. We should probably do
                //       something smarter.
                let methods = fns.iter()
                        .map( | sig |
                            ComMethodInfo::new( sig, ts ) )
                        .filter_map( Result::ok )
                        .collect::<Vec<_>>();

                Ok( ( ts, ComInterfaceVariant {
                    display_name: itf_ident.clone(),
                    unique_name : itf_unique_ident,
                    unique_base_interface : unique_base,
                    type_system : ts,
                    iid,
                    methods,
                } ) )
            } ).collect::<Result<Vec<_>,_>>()? );

        Ok( ComInterface {
            display_name: itf_ident,
            base_interface: base,
            item_type: itf_type,
            is_unsafe : unsafety.is_some(),
            visibility,
            variants,
        } )
    }
/// Creates ComInterface from AST elements.
Creates ComInterface from AST elements.
Creates ComInterface from AST elements .
pub fn from_ast(
        crate_name : &str,
        attr : TokenStream,
        item : &::syn::Item,
    ) -> ParseResult< ComInterface >
    {
        let attr : ComInterfaceAttr = ::syn::parse2( attr )
            .map_err( |_| ParseError::ComInterface(
                    item.get_ident().unwrap().to_string(),
                    "Attribute syntax error".into() ) )?;
        // Get the interface details. As [com_interface] can be applied to both
        // impls and traits this handles both of those.
        let ( itf_ident, fns, itf_type, unsafety ) =
                ::utils::get_ident_and_fns( item )
                    .ok_or_else( || ParseError::ComInterface(
                            item.get_ident().unwrap().to_string(),
                            "Unsupported associated item".into() ) )?;
        // The second argument is the optional base class. If there's no base
        // class defined, use IUnknown as the default. The value of NO_BASE will
        // construct an interface that has no base class.
        //
        // In practice the NO_BASE should be used ONLY for the IUnknown itself.
        let base = attr.base()
                .map_err( |msg| ParseError::ComInterface(
                    item.get_ident().unwrap().to_string(), msg ) )?;
        let base = match base {
            Some( b ) => if b == "NO_BASE" { None } else { Some( b.to_owned() ) },
            None => Some( Ident::new( "IUnknown", Span::call_site() ) ),
        };
        // Visibility for trait interfaces is the visibility of the trait.
        //
        // For implicit interfaces (impl Struct) the visibility is always public.
        // These interfaces should only exist for COM types that are meant to be
        // called from external sources as they can't be impl'd for random ComItf.
        //
        // Note this may conflict with visibility of the actual [com_class], but
        // nothing we can do for this really.
        let visibility = if let ::syn::Item::Trait( ref t ) = *item {
                    t.vis.clone()
                } else {
                    parse_quote!( pub )
                };
        let variants = OrderMap::from_iter(
            [ ModelTypeSystem::Automation, ModelTypeSystem::Raw ].iter().map( |&ts| {
            let itf_unique_ident = Ident::new(
                    &format!( "{}_{:?}", itf_ident.to_string(), ts ), Span::call_site() );
                // IUnknown interfaces do not have type system variants.
                let unique_base = match base {
                    Some( ref iunk ) if iunk == "IUnknown" => base.clone(),
                    ref b => b.as_ref().map( |b| Ident::new( &format!( "{}_{:?}", b, ts ), Span::call_site() ) )
                };
                let iid_attr = attr.iid( ts )
                        .map_err( |msg| ParseError::ComInterface(
                            item.get_ident().unwrap().to_string(), msg ) )?;
                let iid = match iid_attr {
                    Some( iid ) => GUID::parse( &iid.value() )
                        .map_err( |_| ParseError::ComInterface(
                                item.get_ident().unwrap().to_string(),
                                "Bad IID format".into() ) )?,
                    None => ::utils::generate_iid(
                            crate_name, &itf_unique_ident.to_string(), ts )
                };
                // Read the method details.
                //
                // TODO: Currently we ignore invalid methods. We should probably do
                //       something smarter.
                let methods = fns.iter()
                        .map( | sig |
                            ComMethodInfo::new( sig, ts ) )
                        .filter_map( Result::ok )
                        .collect::<Vec<_>>();
                Ok( ( ts, ComInterfaceVariant {
                    display_name: itf_ident.clone(),
                    unique_name : itf_unique_ident,
                    unique_base_interface : unique_base,
                    type_system : ts,
                    iid,
                    methods,
                } ) )
            } ).collect::<Result<Vec<_>,_>>()? );
        Ok( ComInterface {
            display_name: itf_ident,
            base_interface: base,
            item_type: itf_type,
            is_unsafe : unsafety.is_some(),
            visibility,
            variants,
        } )
    }
pub fn from_ast ( crate_name : & str , attr : TokenStream , item : & :: syn :: Item , ) -> ParseResult < ComInterface > { let attr : ComInterfaceAttr = :: syn :: parse2 ( attr ) . map_err ( | _ | ParseError :: ComInterface ( item . get_ident ( ) . unwrap ( ) . to_string ( ) , " " . into ( ) ) ) ? ; // Get the interface details. As [com_interface] can be applied to both // impls and traits this handles both of those. let ( itf_ident , fns , itf_type , unsafety ) = :: utils :: get_ident_and_fns ( item ) . ok_or_else ( | | ParseError :: ComInterface ( item . get_ident ( ) . unwrap ( ) . to_string ( ) , " " . into ( ) ) ) ? ; // The second argument is the optional base class. If there's no base // class defined, use IUnknown as the default. The value of NO_BASE will // construct an interface that has no base class. // // In practice the NO_BASE should be used ONLY for the IUnknown itself. let base = attr . base ( ) . map_err ( | msg | ParseError :: ComInterface ( item . get_ident ( ) . unwrap ( ) . to_string ( ) , msg ) ) ? ; let base = match base { Some ( b ) => if b == " " { None } else { Some ( b . to_owned ( ) ) } , None => Some ( Ident :: new ( " " , Span :: call_site ( ) ) ) , } ; // Visibility for trait interfaces is the visibility of the trait. // // For implicit interfaces (impl Struct) the visibility is always public. // These interfaces should only exist for COM types that are meant to be // called from external sources as they can't be impl'd for random ComItf. // // Note this may conflict with visibility of the actual [com_class], but // nothing we can do for this really. let visibility = if let :: syn :: Item :: Trait ( ref t ) = * item { t . vis . clone ( ) } else { parse_quote ! ( pub ) } ; let variants = OrderMap :: from_iter ( [ ModelTypeSystem :: Automation , ModelTypeSystem :: Raw ] . iter ( ) . map ( | & ts | { let itf_unique_ident = Ident :: new ( & format ! ( " " itf_ident to_string ( ) ts ) , Span :: call_site ( ) ) ; // IUnknown interfaces do not have type system variants. let unique_base = match base { Some ( ref iunk ) if iunk == " " => base . clone ( ) , ref b => b . as_ref ( ) . map ( | b | Ident :: new ( & format ! ( " " b ts ) , Span :: call_site ( ) ) ) } ; let iid_attr = attr . iid ( ts ) . map_err ( | msg | ParseError :: ComInterface ( item . get_ident ( ) . unwrap ( ) . to_string ( ) , msg ) ) ? ; let iid = match iid_attr { Some ( iid ) => GUID :: parse ( & iid . value ( ) ) . map_err ( | _ | ParseError :: ComInterface ( item . get_ident ( ) . unwrap ( ) . to_string ( ) , " " . into ( ) ) ) ? , None => :: utils :: generate_iid ( crate_name , & itf_unique_ident . to_string ( ) , ts ) } ; // Read the method details. // // TODO: Currently we ignore invalid methods. We should probably do //       something smarter. let methods = fns . iter ( ) . map ( | sig | ComMethodInfo :: new ( sig , ts ) ) . filter_map ( Result :: ok ) . collect :: < Vec < _ > > ( ) ; Ok ( ( ts , ComInterfaceVariant { display_name : itf_ident . clone ( ) , unique_name : itf_unique_ident , unique_base_interface : unique_base , type_system : ts , iid , methods , } ) ) } ) . collect :: < Result < Vec < _ > , _ > > ( ) ? ) ; Ok ( ComInterface { display_name : itf_ident , base_interface : base , item_type : itf_type , is_unsafe : unsafety . is_some ( ) , visibility , variants , } ) }
Creates ComInterface from AST elements.
Creates ComInterface from AST elements .
crate_name
&str
attr
TokenStream
item
&::syn::Item