aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2021-11-21 20:27:01 +0100
committerMartin Fischer <martin@push-f.com>2021-11-21 20:27:01 +0100
commit3234eb03a9150e14ecabaa63a8a45c27caf9698b (patch)
tree0727e6d8247bd25f8a2ab268267273dde2337f53
parent0dd8413eca378e5dc2e6cbdc6f9c6f8bde604e4a (diff)
improve README
-rw-r--r--README.md67
1 files changed, 41 insertions, 26 deletions
diff --git a/README.md b/README.md
index 1204661..58abda6 100644
--- a/README.md
+++ b/README.md
@@ -71,13 +71,6 @@ automatically also implements `DynClient`!
## How does this actually work?
-Dynamize recognizes the `Result<T, E>` in the return type and knows that
-associated types in `T` need to be mapped with `map()` whereas associated types
-in `E` need to be mapped with `map_err()`. Dynamize also understands
-`Option<T>`. Thanks to recursion Dynamize can deal with arbitrarily nested
-options and results, so e.g. `Result<Option<Self::Item>, Self::Error>` also
-just works.
-
The destination type of an associated type is
determined by looking at its first trait bound:
@@ -86,6 +79,47 @@ determined by looking at its first trait bound:
* `SomeTrait` is mapped to `Box<dyn SomeTrait>`
(for this `SomeTrait` of course needs to be object-safe)
+Dynamize can convert associated types in:
+
+* return types, e.g. `fn example(&self) -> Self::A`
+* callback parameters, e.g. `fn example<F: Fn(Self::A)>(&self, f: F)`
+
+Dynamize also understands if you wrap associated types in the following types:
+
+* `Option<_>`
+* `Result<_, _>`
+* `some::module::Result<_>` (assumed to be a Result type alias)
+* `&mut dyn Iterator<Item = _>`
+
+Note that since these are resolved recursively you can actually nest these
+arbitrarily so e.g. the following also just works:
+
+```rs
+fn example(&self) -> Result<Option<Self::Item>, Self::Error>;
+```
+
+## How does dynamize deal with method generics?
+
+In order to be object-safe methods must not have generics, so dynamize simply
+moves them to the trait definition:
+
+```rs
+trait Gen {
+ fn foobar<A>(&self, a: A) -> A;
+}
+```
+
+becomes
+
+```rs
+trait DynGen<A> {
+ fn foobar(&self, a: A) -> A;
+}
+```
+
+If two method type parameters have the same name, dynamize enforces that they
+also have the same bounds and only adds the parameter once to the trait.
+
## Dynamize supports async
Dynamize supports async out of the box. Since Rust however does not yet support
@@ -109,22 +143,3 @@ generated dynamized trait. The `#[blanket_impl_attr(...)]` attribute lets you
attach macro attributes to the generated blanket implementation. Note that it
is important that the dynamize attribute comes before the `async_trait`
attribute.
-
-## Dynamize supports Fn, FnOnce & FnMut
-
-The following also just works:
-
-```rust ignore
-#[dynamize::dynamize]
-trait TraitWithCallback {
- type A: SomeTrait;
-
- fn fun_with_callback<F: Fn(Self::A)>(&self, a: F);
-}
-```
-
-Note that since in order to be object-safe methods must not have generics,
-dynamize simply moves the generic from the method to the trait definition.
-
-If two method type parameters have the same name, dynamize enforces that they
-also have the same bounds and only adds the parameter once to the trait.