use std::sync::Arc;
use tokio::task::futures::TaskLocalFuture;
use crate::{
error::ServiceNotFoundError,
scope::{Scope, ScopeProvider},
};
tokio::task_local! {
static TASK_SCOPE: Arc<Scope>;
}
pub struct TaskScopeProvider;
impl super::ScopeDefault for TaskScopeProvider {
fn initialize(_scope: Arc<Scope>) { unreachable!() }
fn update(_scope: Arc<Scope>) { unreachable!() }
}
impl TaskScopeProvider {
pub fn initialize_async<F>(scope: Scope, fut: F) -> TaskLocalFuture<Arc<Scope>, F>
where
F: Future,
{
TASK_SCOPE.scope(Arc::new(scope), fut)
}
pub fn initialize_sync<F, R>(scope: Scope, fun: F) -> R
where
F: FnOnce() -> R,
{
TASK_SCOPE.sync_scope(Arc::new(scope), fun)
}
pub fn update_async<F>(scope: Scope, fut: F) -> TaskLocalFuture<Arc<Scope>, F>
where
F: Future,
{
TASK_SCOPE.scope(Arc::new(scope), fut)
}
pub fn update_sync<F, R>(scope: Scope, fun: F) -> R
where
F: FnOnce() -> R,
{
TASK_SCOPE.sync_scope(Arc::new(scope), fun)
}
}
impl ScopeProvider for TaskScopeProvider {
fn provide_scope(&self) -> Result<Arc<Scope>, ServiceNotFoundError> { Ok(TASK_SCOPE.get()) }
}