yaaral 0.5.3

yet another async runtime abstraction library
Documentation
//! Implementation of the Runtime for the `tokio` runtime

use std::future::Future;
use std::sync::Arc;
use tokio::task::{JoinError, JoinHandle};

use crate::prelude::*;

impl<T: Send> TaskHandle for JoinHandle<Result<T, JoinError>> {
    type Output = T;
    type JoinError = JoinError;
    async fn join(self) -> Result<Self::Output, Self::JoinError> {
        self.await?
    }
    fn abort(self) {
        JoinHandle::abort(&self);
    }
    async fn cancel(self) {
        JoinHandle::abort(&self);
        let _ = self.await;
    }
    fn detach(self) {}
}

/// Runtime from the `tokio` crate
#[derive(Clone)]
pub struct Runtime {
    #[allow(dead_code)]
    runtime: Option<Arc<tokio::runtime::Runtime>>,
    handle: tokio::runtime::Handle,
}

impl Runtime {
    /// Access the current tokio runtime. This will panic, if called outside of a tokio runtime.
    pub fn current() -> Runtime {
        Self {
            runtime: None,
            handle: tokio::runtime::Handle::current(),
        }
    }
}

impl From<tokio::runtime::Handle> for Runtime {
    fn from(handle: tokio::runtime::Handle) -> Self {
        Self {
            runtime: None,
            handle,
        }
    }
}
impl From<&tokio::runtime::Handle> for Runtime {
    fn from(handle: &tokio::runtime::Handle) -> Self {
        Self {
            runtime: None,
            handle: handle.to_owned(),
        }
    }
}

impl crate::TaskInterface for Runtime {
    type TaskHandle<T: 'static + Send> = JoinHandle<Result<T, Self::JoinError>>;
    type SpawnError = Infallible;
    type JoinError = JoinError;

    fn spawn_task<F, T>(
        &self,
        future: F,
    ) -> Result<crate::utils::TaskHandle<Self::TaskHandle<F::Output>>, Self::SpawnError>
    where
        F: Future<Output = T> + Send + 'static,
        T: Send + 'static,
    {
        Ok(self.handle.spawn(async move { Ok(future.await) }).into())
    }
    fn block_on<F: Future>(&self, future: F) -> F::Output {
        self.handle.block_on(future)
    }
}

impl CreationInterface for Runtime {
    type NewError = std::io::Error;
    fn new(config: Config) -> Result<Self, Self::NewError> {
        let mut builder = tokio::runtime::Builder::new_multi_thread();
        builder.enable_all();
        if let Some(prefix) = config.prefix {
            builder.thread_name(prefix);
        }
        if let Some(thread_count) = config.thread_count {
            builder.worker_threads(thread_count);
        }

        let runtime = builder.build()?;
        let handle = runtime.handle().clone();
        Ok(Self {
            runtime: Some(Arc::new(runtime)),
            handle,
        })
    }
}