future_form 0.3.1

Abstractions over Send and !Send futures
Documentation
use super::*;

// Test Fn bounds with multiple arguments (commas inside parentheses)
trait CallbackProcessor<K: FutureForm> {
    fn process(&self) -> K::Future<'_, u32>;
}

struct FnHolder<F>(F);

#[future_form(Sendable where F: Fn(u32, String) -> bool + Send, Local)]
impl<K: FutureForm, F: Fn(u32, String) -> bool> CallbackProcessor<K> for FnHolder<F> {
    fn process(&self) -> K::Future<'_, u32> {
        K::from_future(async { 42 })
    }
}

#[tokio::test]
async fn test_fn_bounds_with_commas_local() {
    let holder: FnHolder<fn(u32, String) -> bool> = FnHolder(|_, _| true);
    let result =
        <FnHolder<fn(u32, String) -> bool> as CallbackProcessor<Local>>::process(&holder).await;
    assert_eq!(result, 42);
}

#[tokio::test]
async fn test_fn_bounds_with_commas_sendable() {
    let holder: FnHolder<fn(u32, String) -> bool> = FnHolder(|_, _| true);
    let result =
        <FnHolder<fn(u32, String) -> bool> as CallbackProcessor<Sendable>>::process(&holder).await;
    assert_eq!(result, 42);
}

// Test tuple types in bounds
trait TupleHandler<K: FutureForm> {
    fn handle(&self) -> K::Future<'_, (u32, String)>;
}

#[derive(Clone)]
struct TupleStruct;

#[future_form(Sendable where Self: Clone + Send, Local where Self: Clone)]
impl<K: FutureForm> TupleHandler<K> for TupleStruct {
    fn handle(&self) -> K::Future<'_, (u32, String)> {
        K::from_future(async { (42, "hello".to_string()) })
    }
}

#[tokio::test]
async fn test_tuple_return_type() {
    let result = <TupleStruct as TupleHandler<Local>>::handle(&TupleStruct).await;
    assert_eq!(result, (42, "hello".to_string()));
}