Expand description
Lightweight dynamic dispatch, intended for embedded use.
Ref<dyn Trait> and RefMut<dyn Trait> wrap a pointer and metadata necessary to call
trait methods, and Deref into a tinydyn trait object that implements the Trait.
Traits must currently opt-in by annotating with tinydyn.
This defines an alternate, lighter weight vtable, and if the trait has one method, eliminates
it entirely by putting the function pointer inline.
This does not affect normal behavior of the trait, and can still be made into a dyn Trait.
This, however, would be wasteful.
§Example
use tinydyn::{tinydyn, Ref, RefMut};
#[tinydyn]
trait Spam {
fn ham(&mut self) -> i32;
fn eggs(&self) -> i32 { 10 }
}
impl Spam for i32 {
fn ham(&self) -> i32 {
*self += 2;
*self - 1
}
}
let mut x = 15;
// Like upcasting to `&dyn Foo`, but with a lighter weight vtable.
let mut mutable: RefMut<dyn Foo> = RefMut::new(&mut x);
assert_eq!(mutable.ham(), 16);
assert_eq!(mutable.eggs(), 10);
// mutable.into() would instead consume and have the same lifetime as `mutable`
let shared: Ref<dyn Foo> = mutable.as_ref();
assert_eq!(shared.eggs(), 10);
// Cannot call `shared.ham()` as it's a shared ref and can't call `&mut self` methods.
assert_eq!(x, 17);§Planned features
⚠️ This library is not yet tested enough to be production ready ⚠️
-
&selfand&mut selfmethods -
+ Sendand+ Synctrait objects -
lifetime
wherebounds on methods - lifetime generics on methods
- implementing on foreign traits/custom vtables
-
implementations for common
core/stdtraits (nevercore::fmt::{Debug, Display}as they use&dyn) - generics on the trait
- associated types
-
supertraits
-
upcasting
Ref<dyn Subtrait>toRef<dyn Supertrait>
-
upcasting
-
Pin<&mut self>and similar non-reference object-safe receivers -
wherebounds on the trait -
where Self: Sizedmethods (and appropriate exclusion from the vtable)- non-lifetime generics on methods
-
non-lifetime
wherebounds on methods -
An attribute to manually exclude a method from a vtable, necessary for bounds
including subtraits or aliases of
Sized
-
An
tinydyn(inline_vtable[ = "all"])attribute to force inlining of the vtable into the wide pointer. This would require the metadata type to always be carried in the trait. -
Put
Refvtables inline even ifRefMutwon’t. Ex: 1&selfand 1&mut selfmethod. - UI tests to ensure proper rejection and error message quality
§Implementing on foreign traits
Implementing on foreign traits is not yet supported, and is an ergonomic and safety challenge
to get right, especially with regards to default methods.
As a workaround, you can create a local helper trait that contains the desired methods and
blanket implements for all T: TargetTrait.
This functionality might be added by tinydyn in the future, or a better solution like defining
custom local vtables for foreign traits.
Traits with supertraits that wish to use this version of tinydyn have a similar workaround.
§Design
See the README for how this library is designed and works.
Structs§
- Ref
- A shared reference to a tinydyn trait object.
- RefMut
- A mutable reference to a tinydyn trait object.
Traits§
- Build
DynMeta - Builds the tinydyn trait metadata for a given type.
- DynTrait
- A trait object that works with
tinydyn, including any extra bounds. - Implements
- Types that could be cast to the given
Traittrait object. - Plain
Dyn - A trait object supported by
tinydyn.