diff options
Diffstat (limited to 'macros')
| -rw-r--r-- | macros/src/lib.rs | 116 | 
1 files changed, 106 insertions, 10 deletions
diff --git a/macros/src/lib.rs b/macros/src/lib.rs index bcb4449..13037e4 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -10,6 +10,8 @@ use syn::{      Block,      FnArg,      GenericArgument, +    GenericParam, +    Generics,      ImplItem,      ImplItemMethod,      ItemTrait, @@ -22,6 +24,7 @@ use syn::{      TypeBareFn,      TypeParamBound,      Visibility, +    WherePredicate,  };  use crate::expectation::Expectation; @@ -174,6 +177,13 @@ fn get_type_replaced_impl_item_methods(      mock_ident: &Ident,  ) -> Vec<ImplItemMethod>  { +    let target_path = create_path!(Self); + +    let replacement_path = Path::new( +        WithLeadingColons::No, +        [PathSegment::new(mock_ident.clone(), None)], +    ); +      impl_items          .into_iter()          .filter_map(|item| match item { @@ -186,11 +196,8 @@ fn get_type_replaced_impl_item_methods(                          FnArg::Typed(mut typed_arg) => {                              typed_arg.ty = Box::new(replace_path_in_type(                                  *typed_arg.ty, -                                &create_path!(Self), -                                &Path::new( -                                    WithLeadingColons::No, -                                    [PathSegment::new(mock_ident.clone(), None)], -                                ), +                                &target_path, +                                &replacement_path,                              ));                              FnArg::Typed(typed_arg) @@ -205,16 +212,19 @@ fn get_type_replaced_impl_item_methods(                          r_arrow,                          Box::new(replace_path_in_type(                              *return_type, -                            &create_path!(Self), -                            &Path::new( -                                WithLeadingColons::No, -                                [PathSegment::new(mock_ident.clone(), None)], -                            ), +                            &target_path, +                            &replacement_path,                          )),                      ),                      ReturnType::Default => ReturnType::Default,                  }; +                item_method.sig.generics = replace_path_in_generics( +                    item_method.sig.generics, +                    &target_path, +                    &replacement_path, +                ); +                  Some(item_method)              }              _ => None, @@ -222,6 +232,71 @@ fn get_type_replaced_impl_item_methods(          .collect()  } +fn replace_path_in_generics( +    mut generics: Generics, +    target_path: &Path, +    replacement_path: &Path, +) -> Generics +{ +    generics.params = generics +        .params +        .into_iter() +        .map(|generic_param| match generic_param { +            GenericParam::Type(mut type_param) => { +                type_param.bounds = type_param +                    .bounds +                    .into_iter() +                    .map(|bound| { +                        replace_type_param_bound_paths( +                            bound, +                            target_path, +                            replacement_path, +                        ) +                    }) +                    .collect(); + +                GenericParam::Type(type_param) +            } +            generic_param => generic_param, +        }) +        .collect(); + +    generics.where_clause = generics.where_clause.map(|mut where_clause| { +        where_clause.predicates = where_clause +            .predicates +            .into_iter() +            .map(|predicate| match predicate { +                WherePredicate::Type(mut predicate_type) => { +                    predicate_type.bounded_ty = replace_path_in_type( +                        predicate_type.bounded_ty, +                        target_path, +                        replacement_path, +                    ); + +                    predicate_type.bounds = predicate_type +                        .bounds +                        .into_iter() +                        .map(|bound| { +                            replace_type_param_bound_paths( +                                bound, +                                target_path, +                                replacement_path, +                            ) +                        }) +                        .collect(); + +                    WherePredicate::Type(predicate_type) +                } +                predicate => predicate, +            }) +            .collect(); + +        where_clause +    }); + +    generics +} +  fn replace_path_in_type(ty: Type, target_path: &Path, replacement_path: &Path) -> Type  {      match ty { @@ -426,3 +501,24 @@ fn replace_type_bare_fn_type_paths(      type_bare_fn  } + +fn replace_type_param_bound_paths( +    type_param_bound: TypeParamBound, +    target_path: &Path, +    replacement_path: &Path, +) -> TypeParamBound +{ +    match type_param_bound { +        TypeParamBound::Trait(mut trait_bound) => { +            if &trait_bound.path == target_path { +                trait_bound.path = replacement_path.clone(); +            } else { +                trait_bound.path = +                    replace_path_args(trait_bound.path, target_path, replacement_path); +            } + +            TypeParamBound::Trait(trait_bound) +        } +        TypeParamBound::Lifetime(lifetime) => TypeParamBound::Lifetime(lifetime), +    } +}  | 
