use std::cell::RefCell;
use std::future::Future;
use crate::context::futures::TaskLocalFuture;
#[derive(Debug)]
pub struct LocalKey<T: 'static>(pub(crate) std::thread::LocalKey<RefCell<Option<T>>>);
impl<T: 'static> LocalKey<T> {
#[doc(hidden)]
pub const fn new(key: std::thread::LocalKey<RefCell<Option<T>>>) -> Self {
LocalKey(key)
}
pub(crate) fn scope_internal<F>(&'static self, value: T, f: F) -> TaskLocalFuture<T, F>
where
F: Future,
{
TaskLocalFuture {
slot: Some(value),
local_key: self,
future: f,
}
}
pub fn scope<F>(&'static self, value: T, f: F) -> impl Future<Output = F::Output>
where
F: Future,
T: Unpin,
{
self.scope_internal(value, f)
}
pub fn with<F, R>(&'static self, f: F) -> R
where
F: FnOnce(Option<&T>) -> R,
{
self.0.with(|slot| {
let value = slot.borrow();
f(value.as_ref())
})
}
pub fn with_mut<F, R>(&'static self, f: F) -> R
where
F: FnOnce(Option<&mut T>) -> R,
{
self.0.with(|slot| {
let mut value = slot.borrow_mut();
f(value.as_mut())
})
}
pub fn get(&'static self) -> T
where
T: Copy,
{
self.0.with(|slot| {
let value = slot.borrow();
value.expect("Task-local not set")
})
}
pub fn set(&'static self, value: T) {
self.0.set(Some(value))
}
pub fn replace(&'static self, value: T) -> T {
self.0.replace(Some(value)).expect("Task-local not set")
}
}