diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/gats.rs | 17 | ||||
-rw-r--r-- | tests/tests.rs | 152 |
2 files changed, 169 insertions, 0 deletions
diff --git a/tests/gats.rs b/tests/gats.rs new file mode 100644 index 0000000..92e483c --- /dev/null +++ b/tests/gats.rs @@ -0,0 +1,17 @@ +//! This test can be run with `cargo +nightly test --features=nightly` +#![cfg_attr(feature = "nightly", feature(generic_associated_types))] + +#[cfg(feature = "nightly")] +mod test_gats { + #[dynamize::dynamize] + pub trait MyTrait { + type A<'a>: Into<&'a str>; + + fn test1<'b>(&self) -> Self::A<'b>; + } + + fn test<T: MyTrait>(mut some: T) { + let dyn_trait: &dyn DynMyTrait = &some; + let _: &str = dyn_trait.test1(); + } +} diff --git a/tests/tests.rs b/tests/tests.rs new file mode 100644 index 0000000..6bccc04 --- /dev/null +++ b/tests/tests.rs @@ -0,0 +1,152 @@ +#![allow(dead_code)] + +#[test] +fn it_works() { + use dynamize::dynamize; + + mod some { + pub mod module { + pub type Result<T> = std::io::Result<T>; + } + } + + #[dynamize] + /// This is a great trait! + pub trait MyTrait { + type A: Into<String>; + // if there are multiple Into bounds the first one is used + type B: Into<i32> + Into<u64>; + + fn test1(&self) -> Self::A; + fn test2(&self) -> Self::B; + fn test3(&self) -> Option<Self::B>; + fn test4(&self) -> Result<(), Self::A>; + fn test5(&self) -> Result<Self::A, ()>; + /// some method documentation + fn test6(&self) -> Result<Self::A, Self::B>; + + #[allow(clippy::type_complexity)] + fn test7(&self) -> Result<Option<Option<Self::A>>, Option<Option<Self::B>>>; + + // also support Result type aliases with a fixed error type + fn test8(&self) -> some::module::Result<Self::A>; + + // fn test9(&self) -> &dyn Iterator<Item = Self::A>; + + fn mut1(&mut self) -> Self::A; + + fn safe1(&self); + fn safe2(&self, num: i32) -> i32; + fn safe3<'a>(&self, text: &'a str) -> &'a str; + fn safe4(&self) -> Option<i32>; + + // non-dispatchable functions are skipped + fn non_dispatch1(); + fn non_dispatch2(num: i32); + fn non_dispatch3(self) -> Self::A; + fn non_dispatch4(&self) + where + Self: Sized; + } + + fn test<T: MyTrait>(mut some: T) { + let dyn_trait: &dyn DynMyTrait = &some; + let _: String = dyn_trait.test1(); + let _: i32 = dyn_trait.test2(); + let _: Option<i32> = dyn_trait.test3(); + let _: Result<(), String> = dyn_trait.test4(); + let _: Result<String, ()> = dyn_trait.test5(); + let _: Result<String, i32> = dyn_trait.test6(); + let _: Result<Option<Option<String>>, Option<Option<i32>>> = dyn_trait.test7(); + + let dyn_trait: &mut dyn DynMyTrait = &mut some; + dyn_trait.mut1(); + + let _: () = dyn_trait.safe1(); + let _: i32 = dyn_trait.safe2(0); + let _: &str = dyn_trait.safe3("test"); + let _: Option<i32> = dyn_trait.safe4(); + } +} + +#[dynamize::dynamize] +trait Foo<X> { + type A: Into<String>; + + fn foobar(&self, x: X) -> Self::A; +} + +#[dynamize::dynamize] +trait Bar<X> { + fn foobar<A>(&self, x: X) -> A; +} + +fn test<T: Bar<X>, X, A>(some: T) { + let _dyn_trait: &dyn DynBar<X, A> = &some; +} + +#[dynamize::dynamize] +trait Bar1<X> { + fn foobar<A>(&self, x: X) -> A; + fn foobar1<B>(&self, x: X) -> B; + fn foobar2<C>(&self, x: X) -> C; +} + +fn test1<T: Bar1<X>, X, A, B, C>(some: T) { + let _dyn_trait: &dyn DynBar1<X, A, B, C> = &some; +} + +#[dynamize::dynamize] +trait Buz<X> { + type C: Into<String>; + + fn foobar<A>(&self, x: X) -> Result<A, Self::C>; +} + +fn test2<T: Buz<X>, X, A>(some: T, x: X) -> Result<A, String> { + let dyn_trait: &dyn DynBuz<X, A> = &some; + dyn_trait.foobar(x) +} + +#[dynamize::dynamize] +trait Gen { + fn foobar<A>(&self, a: A) -> A; +} + +use async_trait::async_trait; + +#[dynamize::dynamize] +#[dyn_trait_attr(async_trait)] +#[blanket_impl_attr(async_trait)] +#[async_trait] +trait SomeTraitWithAsync: Sync { + type A: Into<String>; + async fn test1(&self) -> Self::A; +} + +async fn async_test<T: SomeTraitWithAsync>(some: T) { + let dyn_trait: &dyn DynSomeTraitWithAsync = &some; + let _: String = dyn_trait.test1().await; +} + +#[dynamize::dynamize] +trait TraitWithCallback { + type A: Into<String>; + fn fun_with_callback<F: Fn(Self::A)>(&self, a: F); + + fn fun_with_callback1<X: Fn(Option<Self::A>)>(&self, a: X); + + fn fun_with_callback2<Y: Fn(i32, Option<Self::A>, String) -> bool>(&self, a: Y); + + fn fun_with_callback3<Z: Fn(i32)>(&self, a: Z); +} + +#[dynamize::dynamize] +#[dyn_trait_attr(async_trait)] +#[blanket_impl_attr(async_trait)] +#[async_trait] +trait AsyncWithCallback: Sync { + type A: Into<String>; + async fn test1(&self) -> Self::A; + async fn fun_with_callback<F: Fn(Self::A) + Sync + Send + 'static>(&self, a: F); +} |