summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-04-01 15:00:06 +0200
committerHampusM <hampus@hampusmat.com>2023-04-01 15:03:29 +0200
commitba865b581fbc1d0589b402b028f2bce70332891b (patch)
tree752e7be1150b8a5412b4351803edc6970916d9fa
parent1628732d6514670fe2108e5063e9d5ba7166ad94 (diff)
feat: allow for usage of associated types of generics
-rw-r--r--examples/generic_method.rs33
-rw-r--r--macros/src/expectation.rs12
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()}
}
}