#[cfg(feature = "alloc")]
use ordofp_core::transformers::{EitherT, OptionT, ReaderT, StateT};
#[derive(Clone, Debug)]
struct AppConfig {
database_url: String,
max_retries: u32,
timeout_ms: u64,
}
#[cfg(feature = "alloc")]
fn reader_t_send_sync_example() {
println!("=== ReaderT Send/Sync Example ===");
let config = AppConfig {
database_url: "postgres://localhost:5432".to_string(),
max_retries: 3,
timeout_ms: 1000,
};
println!("Using config: {config:?}");
let fetch_config: ReaderT<AppConfig, Option<String>> = ReaderT::new(|cfg: &AppConfig| {
if cfg.max_retries > 0 && cfg.timeout_ms > 0 {
Some(cfg.database_url.clone())
} else {
None
}
});
let config = AppConfig {
database_url: "postgres://localhost/db".to_string(),
max_retries: 3,
timeout_ms: 5000,
};
let result = std::thread::spawn(move || fetch_config.run(&config))
.join()
.unwrap();
println!(" Database URL: {result:?}");
}
#[cfg(feature = "alloc")]
fn state_t_send_sync_example() {
println!("\n=== StateT Send/Sync Example ===");
#[derive(Clone)]
struct Counter {
value: i32,
operations: Vec<String>,
}
let increment: StateT<Counter, Option<(Counter, i32)>> = StateT::new(|mut c: Counter| {
let old = c.value;
c.value += 1;
c.operations.push("increment".to_string());
Some((c, old))
});
let initial = Counter {
value: 0,
operations: vec![],
};
let result = std::thread::spawn(move || increment.run(initial))
.join()
.unwrap();
if let Some((final_state, old_value)) = result {
println!(" Old value: {old_value}");
println!(" New value: {}", final_state.value);
println!(" Operations: {:?}", final_state.operations);
}
}
#[cfg(feature = "alloc")]
fn option_t_send_example() {
println!("\n=== OptionT Send Example ===");
let computation: OptionT<Result<Option<i32>, String>> = OptionT::some(42);
let mapped = computation.map(|x| x * 2);
let result = std::thread::spawn(move || mapped.run()).join().unwrap();
println!(" Result: {result:?}");
}
#[cfg(feature = "alloc")]
fn either_t_send_example() {
println!("\n=== EitherT Send Example ===");
let computation: EitherT<Option<Result<i32, String>>> = EitherT::right(21);
let doubled = computation.map(|x| x * 2);
let result = std::thread::spawn(move || doubled.run()).join().unwrap();
println!(" Result: {result:?}");
}
#[cfg(feature = "alloc")]
fn combined_transformers_example() {
println!("\n=== Combined Transformers Example ===");
#[derive(Clone)]
struct Config {
multiplier: i32,
}
let step1: ReaderT<Config, Option<i32>> = ReaderT::new(|cfg: &Config| Some(cfg.multiplier));
let step2 = step1.flat_map(|val| {
ReaderT::new(move |cfg: &Config| {
if cfg.multiplier > 0 {
Some(val * 2)
} else {
None
}
})
});
let step3 = step2.map(|val| val + 10);
let config = Config { multiplier: 5 };
let result = std::thread::spawn(move || step3.run(&config))
.join()
.unwrap();
println!(" Result: {result:?}"); }
fn main() {
#[cfg(feature = "alloc")]
{
println!("OrdoFP Async Transformer Compatibility Demo");
println!("============================================\n");
println!("This demonstrates that transformers work with async runtimes.");
println!("All closures passed to ReaderT/StateT must be Send + Sync.\n");
reader_t_send_sync_example();
state_t_send_sync_example();
option_t_send_example();
either_t_send_example();
combined_transformers_example();
println!("\n============================================");
println!("All transformers are compatible with tokio/smol!");
}
#[cfg(not(feature = "alloc"))]
{
println!("This example requires the 'alloc' feature.");
println!("Run with: cargo run --example 07_async_transformers --features alloc");
}
}