use std::{
pin::pin,
sync::Arc,
task::{Context, Poll, Waker},
thread,
};
use crate::thread::Thread;
thread_local! {
static WAKER: Waker = Waker::from(Arc::new(Thread::default()));
}
pub struct Executor;
impl Executor {
pub fn block_on<F: IntoFuture>(f: F) -> F::Output {
let mut f = pin!(f.into_future());
WAKER.with(|waker| {
let mut cx = Context::from_waker(waker);
loop {
match f.as_mut().poll(&mut cx) {
Poll::Ready(x) => return x,
Poll::Pending => thread::park(),
}
}
})
}
}
#[cfg(test)]
mod tests {
#[rustfmt::skip]
use std::{
error,
result,
};
use super::*;
#[rustfmt::skip]
#[test]
fn block_on_result_ok() {
let x: result::Result<(), Box<dyn error::Error>> =
Executor::block_on(async {
Ok(())
});
assert!(x.is_ok());
}
#[rustfmt::skip]
#[test]
fn block_on_result_err() {
let x: result::Result<(), &str> =
Executor::block_on(async {
Err("")
});
assert!(x.is_err());
}
}