Crate dyn_utils

Crate dyn_utils 

Source
Expand description

A utility library for working with trait objects.

Trait objects (i.e. dyn Trait) are unsized and therefore need to be stored in a container such as Box. This crate provides DynObject, a container for trait objects with a generic storage.

storage::Raw stores objects in place, making DynObject<dyn Trait, storage::Raw> allocation-free. On the other hand, storage::RawOrBox falls back to an allocated Box if the object is too large to fit in place.

Avoiding one allocation makes DynObject a good alternative to Box when writing a dyn-compatible version of a trait with return-position impl Trait, such as async methods.

§Examples

use dyn_utils::object::DynObject;

trait Callback {
    fn call(&self, arg: &str) -> impl Future<Output = ()> + Send;
}

// Dyn-compatible version
trait DynCallback {
    fn call<'a>(&'a self, arg: &'a str) -> DynObject<dyn Future<Output = ()> + Send + 'a>;
}

impl<T: Callback> DynCallback for T {
    fn call<'a>(&'a self, arg: &'a str) -> DynObject<dyn Future<Output = ()> + Send + 'a> {
        DynObject::new(self.call(arg))
    }
}

async fn exec_callback(callback: &dyn DynCallback) {
    callback.call("Hello world!").await;
}

This crate also provides dyn_trait proc-macro to achieve the same result as above:

#[dyn_utils::dyn_trait] // generates `DynCallback` trait
trait Callback {
    fn call(&self, arg: &str) -> impl Future<Output = ()> + Send;
}

async fn exec_callback(callback: &dyn DynCallback) {
    callback.call("Hello world!").await;
}

Re-exports§

pub use object::DynObject;

Modules§

object
DynObject implementation.
storage
The storages backing DynObject.

Enums§

TrySync
An async wrapper with an optimized synchronous execution path.

Attribute Macros§

dyn_objectmacros
Make a trait compatible with DynObject.
dyn_traitmacros
Generate a dyn compatible trait from a given trait declaration.
syncmacros
Mark an async method as internally synchronous.