use super::*;
trait Processor<K: FutureForm> {
fn process(&self) -> K::Future<'_, String>;
}
struct Container<T> {
value: T,
}
#[future_form(Sendable where T: Send, Local)]
impl<K: FutureForm, T: Clone + ToString> Processor<K> for Container<T> {
fn process(&self) -> K::Future<'_, String> {
let value = self.value.clone();
K::from_future(async move { value.to_string() })
}
}
#[tokio::test]
async fn test_conditional_bounds_sendable() {
let container = Container {
value: "hello".to_string(),
};
let result = <Container<String> as Processor<Sendable>>::process(&container).await;
assert_eq!(result, "hello");
}
#[tokio::test]
async fn test_conditional_bounds_local() {
use std::rc::Rc;
let container = Container {
value: Rc::<str>::from("world"),
};
let result = <Container<Rc<str>> as Processor<Local>>::process(&container).await;
assert_eq!(result, "world");
}
trait Debugger<K: FutureForm> {
fn debug(&self) -> K::Future<'_, String>;
}
struct Wrapper<T>(T);
#[future_form(Sendable where T: Send, Local where T: core::fmt::Debug)]
impl<K: FutureForm, T: Clone> Debugger<K> for Wrapper<T> {
fn debug(&self) -> K::Future<'_, String> {
K::from_future(async move { "debugged".to_string() })
}
}
#[tokio::test]
async fn test_local_conditional_bounds() {
let wrapper = Wrapper(42i32);
let result = <Wrapper<i32> as Debugger<Local>>::debug(&wrapper).await;
assert_eq!(result, "debugged");
}
#[tokio::test]
async fn test_sendable_conditional_bounds_separate() {
let wrapper = Wrapper(42i32);
let result = <Wrapper<i32> as Debugger<Sendable>>::debug(&wrapper).await;
assert_eq!(result, "debugged");
}
trait MultiLetterParams<K: FutureForm> {
fn process(&self) -> K::Future<'_, String>;
}
struct MultiLetterContainer<Conn, Sig> {
conn: Conn,
sig: Sig,
}
#[future_form(
Sendable where
Conn: Clone + Send,
Sig: Clone + Send,
Local where
Conn: Clone,
Sig: Clone
)]
impl<K: FutureForm, Conn: ToString, Sig: ToString> MultiLetterParams<K>
for MultiLetterContainer<Conn, Sig>
{
fn process(&self) -> K::Future<'_, String> {
let conn = self.conn.to_string();
let sig = self.sig.to_string();
K::from_future(async move { format!("{conn}:{sig}") })
}
}
#[tokio::test]
async fn test_multi_letter_type_params_sendable() {
let container = MultiLetterContainer {
conn: "localhost",
sig: "abc123",
};
let result =
<MultiLetterContainer<&str, &str> as MultiLetterParams<Sendable>>::process(&container)
.await;
assert_eq!(result, "localhost:abc123");
}
#[tokio::test]
async fn test_multi_letter_type_params_local() {
use std::rc::Rc;
let container = MultiLetterContainer {
conn: Rc::from("localhost"),
sig: Rc::from("abc123"),
};
let result =
<MultiLetterContainer<Rc<str>, Rc<str>> as MultiLetterParams<Local>>::process(&container)
.await;
assert_eq!(result, "localhost:abc123");
}