use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio::task;
pub struct JoinHandle<T>(task::JoinHandle<T>);
impl<T> Unpin for JoinHandle<T> {}
impl<T: Send + 'static> Future for JoinHandle<T> {
type Output = T;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.get_mut() {
JoinHandle(handle) => Pin::new(handle)
.poll(cx)
.map(|r| r.expect("tokio spawned task failed")),
}
}
}
#[allow(dead_code)]
pub fn spawn<F>(f: F) -> JoinHandle<F::Output>
where
F: std::future::Future + Send + 'static,
F::Output: Send + 'static,
{
JoinHandle(task::spawn(f))
}
#[allow(dead_code)]
pub fn spawn_blocking<F, T>(f: F) -> JoinHandle<T>
where
F: FnOnce() -> T + Send + 'static,
T: Send + 'static,
{
JoinHandle(task::spawn_blocking(f))
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_tokio_spawn() {
let handle = spawn(async { 1 + 1 });
assert_eq!(handle.await, 2);
}
#[tokio::test]
async fn test_tokio_spawn_blocking() {
let handle = spawn_blocking(|| 1 + 1);
assert_eq!(handle.await, 2);
}
}