diff options
author | HampusM <hampus@hampusmat.com> | 2023-04-01 15:00:06 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2023-04-01 15:03:29 +0200 |
commit | ba865b581fbc1d0589b402b028f2bce70332891b (patch) | |
tree | 752e7be1150b8a5412b4351803edc6970916d9fa | |
parent | 1628732d6514670fe2108e5063e9d5ba7166ad94 (diff) |
feat: allow for usage of associated types of generics
-rw-r--r-- | examples/generic_method.rs | 33 | ||||
-rw-r--r-- | macros/src/expectation.rs | 12 |
2 files changed, 30 insertions, 15 deletions
diff --git a/examples/generic_method.rs b/examples/generic_method.rs index 7283810..c4e3214 100644 --- a/examples/generic_method.rs +++ b/examples/generic_method.rs @@ -1,12 +1,15 @@ -use std::fmt::Display; - use predicates::float::is_close; use ridicule::mock; use ridicule::predicate::function; +trait Haha +{ + type Hello; +} + trait Foo { - fn bar<Baz: Display>(&self, num: u128) -> Baz; + fn bar<Baz: Haha>(&self, num: u128) -> Baz::Hello; fn abc<ThingA, ThingB>(&mut self, thing_a: ThingA, thing_b: ThingB); } @@ -16,18 +19,28 @@ mock! { impl Foo for MockFoo { - fn bar<Baz: Display>(&self, num: u128) -> Baz; + fn bar<Baz: Haha>(&self, num: u128) -> Baz::Hello; fn abc<ThingA, ThingB>(&mut self, thing_a: ThingA, thing_b: ThingB); } } +impl Haha for u16 +{ + type Hello = String; +} + +impl Haha for &str +{ + type Hello = u8; +} + fn main() { let mut mock_foo = MockFoo::new(); mock_foo - .expect_bar() + .expect_bar::<u16>() .returning(|_me, num| { println!("bar was called with {num}"); @@ -35,7 +48,7 @@ fn main() }) .times(3); - mock_foo.expect_bar().returning(|_me, num| { + mock_foo.expect_bar::<&str>().returning(|_me, num| { println!("bar was called with {num}"); 128u8 @@ -52,14 +65,14 @@ fn main() }) .times(1); - assert_eq!(mock_foo.bar::<String>(123), "Hello".to_string()); - assert_eq!(mock_foo.bar::<String>(123), "Hello".to_string()); - assert_eq!(mock_foo.bar::<String>(123), "Hello".to_string()); + assert_eq!(mock_foo.bar::<u16>(123), "Hello".to_string()); + assert_eq!(mock_foo.bar::<u16>(123), "Hello".to_string()); + assert_eq!(mock_foo.bar::<u16>(123), "Hello".to_string()); // Would panic // mock_foo.bar::<String>(123); - assert_eq!(mock_foo.bar::<u8>(456), 128); + assert_eq!(mock_foo.bar::<&str>(456), 128); mock_foo.abc( concat!( diff --git a/macros/src/expectation.rs b/macros/src/expectation.rs index 8120cfd..2e86db0 100644 --- a/macros/src/expectation.rs +++ b/macros/src/expectation.rs @@ -180,7 +180,6 @@ impl Expectation ident: Ident, generics: Generics, phantom_fields: &[PhantomField], - returning_fn: &Type, boxed_predicate_types: &[Type], ) -> ItemStruct { @@ -208,7 +207,9 @@ impl Expectation format_ident!("Option"), Some(AngleBracketedGenericArguments::new( WithColons::No, - [GenericArgument::Type(returning_fn.clone())], + [GenericArgument::Type(Type::BareFn( + TypeBareFn::new([], ReturnType::Default), + ))], )), )], ))), @@ -345,7 +346,6 @@ impl ToTokens for Expectation self.ident.clone(), generics.clone(), phantom_fields, - &returning_fn, &boxed_predicate_types, ); @@ -445,7 +445,7 @@ impl ToTokens for Expectation func: #returning_fn ) -> &mut Self { - self.returning = Some(func); + self.returning = Some(unsafe { std::mem::transmute(func) }); self } @@ -536,7 +536,9 @@ impl ToTokens for Expectation self.call_cnt.fetch_add(1, std::sync::atomic::Ordering::Relaxed); - returning + let returning_ptr: *const _ = returning; + + unsafe { &*returning_ptr.cast()} } } |