use core::convert::Infallible;
use crate::kernel::{BoxFuture, Effect};
pub type Never = Infallible;
#[inline]
pub fn run_blocking<A, E, R>(effect: Effect<A, E, R>, mut env: R) -> Result<A, E>
where
A: 'static,
E: 'static,
R: 'static,
{
let mut fut: BoxFuture<'_, Result<A, E>> = effect.run(&mut env);
let waker = std::task::Waker::noop();
let mut cx = std::task::Context::from_waker(waker);
loop {
match fut.as_mut().poll(&mut cx) {
std::task::Poll::Ready(output) => return output,
std::task::Poll::Pending => std::thread::yield_now(),
}
}
}
#[inline]
pub async fn run_async<A, E, R>(effect: Effect<A, E, R>, mut env: R) -> Result<A, E>
where
A: 'static,
E: 'static,
R: 'static,
{
effect.run(&mut env).await
}
#[cfg(test)]
mod tests {
use super::*;
use crate::kernel::succeed;
mod run_blocking {
use super::*;
#[test]
fn with_success_effect_returns_ok_value() {
let result = run_blocking(succeed::<u8, (), ()>(9), ());
assert_eq!(result, Ok(9));
}
#[test]
fn completes_flat_mapped_effect_without_double_boxing() {
let eff = crate::kernel::succeed::<u8, &'static str, ()>(3)
.flat_map(|n| crate::kernel::succeed(n + 1));
assert_eq!(run_blocking(eff, ()), Ok(4));
}
#[test]
fn with_failure_effect_returns_err_value() {
let result = run_blocking(crate::kernel::fail::<u8, &str, ()>("boom"), ());
assert_eq!(result, Err("boom"));
}
}
mod run_async {
use super::*;
#[test]
fn with_success_effect_returns_ok_value() {
let async_out = pollster::block_on(run_async(succeed::<u8, (), ()>(11), ()));
assert_eq!(async_out, Ok(11));
}
}
}