define_pooled_dyn_cast

Macro define_pooled_dyn_cast 

Source
macro_rules! define_pooled_dyn_cast {
    ($trait_name:ident) => { ... };
    ($trait_name:ident<$($type_param:ident),+ $(,)?>) => { ... };
}
Expand description

Extends pooled item handles to support casting to a trait object.

This macro generates a trait and an accompanying implementations that adds method to cast a pooled value pooled value from an unknown concrete type to a trait object of a specific trait while preserving the semantics of the original handle, returning a handle that dereferences to the trait object instead of the original concrete type.

The generated cast method allows conversion from Pooled<T> to Pooled<dyn Trait> where T implements the trait in question (and equivalently for LocalPooled<T>, RawPooled<T> and RawBlindPooled<T>).

§Parameters

  • trait_name: The trait to enable casting to (e.g., Display, SendUnitFuture). The method name is automatically derived by converting this to snake_case with a cast_ prefix (e.g. cast_display()).
  • trait_name<TypeParams>: A generic trait with type parameters (e.g., SomeFuture<T>). Generates a generic method like cast_some_future::<usize>().

The trait must have at least pub(crate) visibility because the generated code uses that visibility.

For complex trait bounds, define a trait alias first, to simplify the trait to a single name, then use this macro with the trait alias name. You may otherwise experience macro parsing issues.

§Examples

§Basic usage with simple trait

use std::fmt::Display;

use infinity_pool::{BlindPool, BlindPooledMut, define_pooled_dyn_cast};

// Enable casting to Display trait objects
define_pooled_dyn_cast!(Display);

// Function that accepts trait object handles directly
fn process_displayable(handle: BlindPooledMut<dyn Display>) {
    println!("Processing: {}", &*handle);
}

let mut pool = BlindPool::new();
let string_handle = pool.insert("Hello, world!".to_string());
let number_handle = pool.insert(42i32);

// Cast to trait objects and pass to function
process_displayable(string_handle.cast_display());
process_displayable(number_handle.cast_display());

§Complex trait bounds using trait aliases

use std::future::Future;

use infinity_pool::{BlindPool, BlindPooledMut, define_pooled_dyn_cast};

// Define a trait alias for complex trait bounds
trait MyUsizeFuture: Future<Output = Option<usize>> + Send {}

// Blanket implementation for any type that satisfies the bounds
impl<T> MyUsizeFuture for T where T: Future<Output = Option<usize>> + Send {}

// Enable casting using the trait alias
define_pooled_dyn_cast!(MyUsizeFuture);

// Function that accepts the complex trait object
fn process_future(future: &mut BlindPooledMut<dyn MyUsizeFuture>) {
    // Can work with the future as a trait object
    println!("Got a future that returns Option<usize>");
}

let mut pool = BlindPool::new();

let my_future = pool.insert(async { Some(1234_usize) });
let mut my_future = my_future.cast_my_usize_future();

process_future(&mut my_future);