fn mock_trait_methods(struct_ident: &syn::Ident,
                      struct_generics: &syn::Generics,
                      item: &syn::ItemTrait,
                      vis: &syn::Visibility) -> TokenStream
{
    let mut output = TokenStream::new();
    let mut mock_body = TokenStream::new();
    let mut expect_body = TokenStream::new();
    let mock_ident = gen_mock_ident(&struct_ident);

    for trait_item in item.items.iter() {
        match trait_item {
            syn::TraitItem::Const(_) => {
                // Nothing to implement
            },
            syn::TraitItem::Method(meth) => {
                let mod_ident = gen_mod_ident(&struct_ident, Some(&item.ident));
                let generics = merge_generics(&struct_generics, &item.generics);
                let (mock_meth, expect_meth, _cp) = gen_mock_method(
                    &mock_ident,
                    Some(&mod_ident),
                    &meth.attrs[..],
                    &syn::Visibility::Inherited,
                    vis,
                    &meth.sig,
                    Some(&item.ident),
                    &generics
                );
                // trait methods must have inherited visibility.  Expectation
                // methods should have public, for lack of any clearer option.
                mock_meth.to_tokens(&mut mock_body);
                expect_meth.to_tokens(&mut expect_body);
            },
            syn::TraitItem::Type(ty) => {
                if !ty.generics.params.is_empty() {
                    compile_error(ty.generics.span(),
                        "Mockall does not yet support generic associated types");
                }
                if ty.default.is_some() {
                    // Trait normally can't get here (unless the
                    // associated_type_defaults feature is enabled), but we can
                    // get here from mock! if invoked like
                    // mock!{
                    //     Foo { }
                    //     trait Bar {
                    //         type A=B;
                    //     }
                    // }
                    ty.to_tokens(&mut mock_body)
                } else {
                    compile_error(ty.span(), "Associated types must be made concrete for mocking.");
                }
            },
            _ => {
                compile_error(trait_item.span(),
                    "This impl item is not yet supported by MockAll");
            }
        }
    }

    // Put all mock methods in one impl block
    item.unsafety.to_tokens(&mut output);
    let ident = &item.ident;
    let (s_ig, s_sg, s_wc) = struct_generics.split_for_impl();
    let (_t_ig, t_tg, _t_wc) = item.generics.split_for_impl();
    quote!(impl #s_ig #ident #t_tg
           for #mock_ident #s_sg #s_wc {
        #mock_body
    }).to_tokens(&mut output);

    // Put all expect methods in a separate impl block.  This is necessary when
    // mocking a trait impl, where we can't add any new methods
    quote!(impl #s_ig #mock_ident #s_sg #s_wc {
        #expect_body
    }).to_tokens(&mut output);

    output
}
/// Generate mock methods for a Trait
///
/// # Parameters
///
/// * `struct_ident`:       Name of the structure to mock
/// * `struct_generics`:    If provided, use these generic fields for the
///                         Mock struct.  Otherwise, generate the struct's
///                         generics from the Trait
/// * `item`:               The trait whose methods are being mocked
/// * `vis`:                Visibility of the struct
Generate mock methods for a Trait
Generate mock methods for a Trait
fn mock_trait_methods(struct_ident: &syn::Ident,
                      struct_generics: &syn::Generics,
                      item: &syn::ItemTrait,
                      vis: &syn::Visibility) -> TokenStream
{
    let mut output = TokenStream::new();
    let mut mock_body = TokenStream::new();
    let mut expect_body = TokenStream::new();
    let mock_ident = gen_mock_ident(&struct_ident);
    for trait_item in item.items.iter() {
        match trait_item {
            syn::TraitItem::Const(_) => {
                // Nothing to implement
            },
            syn::TraitItem::Method(meth) => {
                let mod_ident = gen_mod_ident(&struct_ident, Some(&item.ident));
                let generics = merge_generics(&struct_generics, &item.generics);
                let (mock_meth, expect_meth, _cp) = gen_mock_method(
                    &mock_ident,
                    Some(&mod_ident),
                    &meth.attrs[..],
                    &syn::Visibility::Inherited,
                    vis,
                    &meth.sig,
                    Some(&item.ident),
                    &generics
                );
                // trait methods must have inherited visibility.  Expectation
                // methods should have public, for lack of any clearer option.
                mock_meth.to_tokens(&mut mock_body);
                expect_meth.to_tokens(&mut expect_body);
            },
            syn::TraitItem::Type(ty) => {
                if !ty.generics.params.is_empty() {
                    compile_error(ty.generics.span(),
                        "Mockall does not yet support generic associated types");
                }
                if ty.default.is_some() {
                    // Trait normally can't get here (unless the
                    // associated_type_defaults feature is enabled), but we can
                    // get here from mock! if invoked like
                    // mock!{
                    //     Foo { }
                    //     trait Bar {
                    //         type A=B;
                    //     }
                    // }
                    ty.to_tokens(&mut mock_body)
                } else {
                    compile_error(ty.span(), "Associated types must be made concrete for mocking.");
                }
            },
            _ => {
                compile_error(trait_item.span(),
                    "This impl item is not yet supported by MockAll");
            }
        }
    }
    // Put all mock methods in one impl block
    item.unsafety.to_tokens(&mut output);
    let ident = &item.ident;
    let (s_ig, s_sg, s_wc) = struct_generics.split_for_impl();
    let (_t_ig, t_tg, _t_wc) = item.generics.split_for_impl();
    quote!(impl #s_ig #ident #t_tg
           for #mock_ident #s_sg #s_wc {
        #mock_body
    }).to_tokens(&mut output);
    // Put all expect methods in a separate impl block.  This is necessary when
    // mocking a trait impl, where we can't add any new methods
    quote!(impl #s_ig #mock_ident #s_sg #s_wc {
        #expect_body
    }).to_tokens(&mut output);
    output
}
fn mock_trait_methods ( struct_ident : & syn :: Ident , struct_generics : & syn :: Generics , item : & syn :: ItemTrait , vis : & syn :: Visibility ) -> TokenStream { let mut output = TokenStream :: new ( ) ; let mut mock_body = TokenStream :: new ( ) ; let mut expect_body = TokenStream :: new ( ) ; let mock_ident = gen_mock_ident ( & struct_ident ) ; for trait_item in item . items . iter ( ) { match trait_item { syn :: TraitItem :: Const ( _ ) => { // Nothing to implement } , syn :: TraitItem :: Method ( meth ) => { let mod_ident = gen_mod_ident ( & struct_ident , Some ( & item . ident ) ) ; let generics = merge_generics ( & struct_generics , & item . generics ) ; let ( mock_meth , expect_meth , _cp ) = gen_mock_method ( & mock_ident , Some ( & mod_ident ) , & meth . attrs [ .. ] , & syn :: Visibility :: Inherited , vis , & meth . sig , Some ( & item . ident ) , & generics ) ; // trait methods must have inherited visibility.  Expectation // methods should have public, for lack of any clearer option. mock_meth . to_tokens ( & mut mock_body ) ; expect_meth . to_tokens ( & mut expect_body ) ; } , syn :: TraitItem :: Type ( ty ) => { if ! ty . generics . params . is_empty ( ) { compile_error ( ty . generics . span ( ) , " " ) ; } if ty . default . is_some ( ) { // Trait normally can't get here (unless the // associated_type_defaults feature is enabled), but we can // get here from mock! if invoked like // mock!{ //     Foo { } //     trait Bar { //         type A=B; //     } // } ty . to_tokens ( & mut mock_body ) } else { compile_error ( ty . span ( ) , " " ) ; } } , _ => { compile_error ( trait_item . span ( ) , " " ) ; } } } // Put all mock methods in one impl block item . unsafety . to_tokens ( & mut output ) ; let ident = & item . ident ; let ( s_ig , s_sg , s_wc ) = struct_generics . split_for_impl ( ) ; let ( _t_ig , t_tg , _t_wc ) = item . generics . split_for_impl ( ) ; quote ! ( impl s_ig ident t_tg for mock_ident s_sg s_wc { mock_body } ) . to_tokens ( & mut output ) ; // Put all expect methods in a separate impl block.  This is necessary when // mocking a trait impl, where we can't add any new methods quote ! ( impl s_ig mock_ident s_sg s_wc { expect_body } ) . to_tokens ( & mut output ) ; output }
Generate mock methods for a Trait
Generate mock methods for a Trait
struct_ident
&syn::Ident
struct_generics
&syn::Generics
item
&syn::ItemTrait
vis
&syn::Visibility
struct_ident
&syn::Ident
struct_generics
&syn::Generics
item
&syn::ItemTrait
vis
&syn::Visibility