use super::{Attr, JoinHandle, Runtime};
use crate::{Error, Result};
use core::future::Future;
pub fn block_on_with<T>(future: T, attr: &Attr) -> Result<T::Output>
where
T: Future,
{
if let Ok(task) = Runtime::local_spawn(future, attr) {
JoinHandle::<T::Output>::new(task).join()
} else {
Err(Error::default())
}
}
pub fn block_on<T>(future: T) -> Result<T::Output>
where
T: Future,
{
block_on_with(future, &Attr::default())
}
#[cfg(test)]
mod test {
extern crate std;
use crate::runtime::*;
use core::time::Duration;
#[test]
fn test_future() {
async fn test_foo() -> i32 {
100
}
let val = local::block_on(test_foo()).unwrap();
assert_eq!(val, 100);
}
#[test]
fn test_task_spawn() {
async fn test_foo() -> i32 {
100
}
async fn test_bar() -> i32 {
task::spawn_local(test_foo()).await.await.unwrap()
+ local::block_on(test_foo()).unwrap()
}
let val = local::block_on(test_bar()).unwrap();
assert_eq!(val, 200);
}
#[test]
fn test_sleep() {
async fn test_sleep(val: i32) -> i32 {
sleep(core::time::Duration::new(1, 0)).await;
yield_now().await;
val + 100
}
let val = local::block_on(test_sleep(100)).unwrap();
assert_eq!(val, 200);
}
#[test]
fn test_ready() {
let val = local::block_on(async {
let mut retn: i32 = 0;
async { 2_i32 }.ready(|result: i32| retn = result).await;
retn
})
.unwrap();
assert_eq!(val, 2);
}
#[test]
fn test_select_any() {
let (r1, r2) = local::block_on(async {
let mut r1: i32 = 0;
let mut r2: i32 = 0;
let t1 = async { 1_i32 }.ready(|result: i32| r1 = result);
let t2 = async { 2_i32 }.ready(|result: i32| r2 = result);
t1.or(t2).await;
(r1, r2)
})
.unwrap();
assert_eq!(r1, 1);
assert_eq!(r2, 0);
}
#[test]
fn test_select_all() {
let (r1, r2) = local::block_on(async {
let mut r1: i32 = 0;
let mut r2: i32 = 0;
let t1 = async { 1_i32 }.ready(|result: i32| r1 = result);
let t2 = async { 2_i32 }.ready(|result: i32| r2 = result);
t1.and(t2).await;
(r1, r2)
})
.unwrap();
assert_eq!(r1, 1);
assert_eq!(r2, 2);
}
#[test]
fn test_or_ready() {
let (r1, r2, r3) = local::block_on(async {
async fn foo() -> i32 {
1
}
async fn bar() -> &'static str {
"hello"
}
async fn baz() -> i32 {
2
}
let mut foo_retn = 0;
let mut bar_retn = "";
let mut baz_retn = 0;
foo()
.ready(|val| foo_retn = val)
.or(bar().ready(|val| bar_retn = val))
.or(baz().ready(|val| baz_retn = val))
.await;
(foo_retn, bar_retn, baz_retn)
})
.unwrap();
assert_eq!(r1, 1);
assert_eq!(r2, "");
assert_eq!(r3, 0);
}
#[test]
fn test_and_ready() {
let (r1, r2, r3) = local::block_on(async {
async fn foo() -> i32 {
1
}
async fn bar() -> &'static str {
"hello"
}
async fn baz() -> i32 {
2
}
let mut foo_retn = 0;
let mut bar_retn = "";
let mut baz_retn = 0;
foo()
.ready(|val| foo_retn = val)
.and(bar().ready(|val| bar_retn = val))
.or(baz().ready(|val| baz_retn = val))
.await;
(foo_retn, bar_retn, baz_retn)
})
.unwrap();
assert_eq!(r1, 1);
assert_eq!(r2, "hello");
assert_eq!(r3, 0);
}
#[test]
fn test_deadline() {
let beg = crate::time::now();
async fn foo() -> Option<i32> {
async fn fun() -> i32 {
sleep(Duration::new(3, 0)).await;
return 1;
}
fun().deadline(Duration::new(1, 0)).await
}
let x = local::block_on(foo()).unwrap();
assert_eq!(None, x);
let end = crate::time::now();
let elapse = end - beg;
assert!(elapse < Duration::new(2, 1000));
}
}