use core::fmt;
use executor::Executor;
use task::{Waker, LocalMap};
pub struct Context<'a> {
waker: &'a Waker,
pub(crate) map: &'a mut LocalMap,
executor: Option<&'a mut Executor>,
}
impl<'a> Context<'a> {
pub fn without_spawn(map: &'a mut LocalMap, waker: &'a Waker) -> Context<'a> {
Context { waker, map, executor: None }
}
pub fn waker(&self) -> &Waker {
self.waker
}
fn with_parts<'b, F, R>(&'b mut self, f: F) -> R
where F: FnOnce(&'b Waker, &'b mut LocalMap, Option<&'b mut Executor>) -> R
{
let executor: Option<&'b mut Executor> = match self.executor {
None => None,
Some(ref mut e) => Some(&mut **e),
};
f(self.waker, self.map, executor)
}
pub fn with_waker<'b>(&'b mut self, waker: &'b Waker) -> Context<'b> {
self.with_parts(|_, map, executor| {
Context { map, executor, waker }
})
}
pub fn with_locals<'b>(&'b mut self, map: &'b mut LocalMap)
-> Context<'b>
{
self.with_parts(move |waker, _, executor| {
Context { map, executor, waker }
})
}
}
if_std! {
use std::boxed::Box;
use Future;
use never::Never;
impl<'a> Context<'a> {
pub fn new(map: &'a mut LocalMap, waker: &'a Waker, executor: &'a mut Executor) -> Context<'a> {
Context { waker, map, executor: Some(executor) }
}
pub fn executor(&mut self) -> &mut Executor {
self.executor
.as_mut().map(|x| &mut **x)
.expect("No default executor found: std-using futures contexts must provide an executor")
}
pub fn spawn<F>(&mut self, f: F)
where F: Future<Item = (), Error = Never> + 'static + Send
{
self.executor()
.spawn(Box::new(f)).unwrap()
}
pub fn with_executor<'b>(&'b mut self, executor: &'b mut Executor)
-> Context<'b>
{
self.with_parts(move |waker, map, _| {
Context { map, executor: Some(executor), waker }
})
}
}
}
impl<'a> fmt::Debug for Context<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Context")
.finish()
}
}