aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2021-11-15 10:29:52 +0100
committerMartin Fischer <martin@push-f.com>2021-11-18 23:36:01 +0100
commit2a8a0601afcb82d90d0766db5a954b70b10f856d (patch)
tree0271062335d450e151598d4ad9aa327ffa0dfaea /tests
publishv0.1.0
Diffstat (limited to 'tests')
-rw-r--r--tests/gats.rs17
-rw-r--r--tests/tests.rs152
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);
+}