diff options
author | Martin Fischer <martin@push-f.com> | 2021-11-21 20:27:01 +0100 |
---|---|---|
committer | Martin Fischer <martin@push-f.com> | 2021-11-21 20:27:01 +0100 |
commit | 3234eb03a9150e14ecabaa63a8a45c27caf9698b (patch) | |
tree | 0727e6d8247bd25f8a2ab268267273dde2337f53 /README.md | |
parent | 0dd8413eca378e5dc2e6cbdc6f9c6f8bde604e4a (diff) |
improve README
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 67 |
1 files changed, 41 insertions, 26 deletions
@@ -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. |