postage/
context.rs

1use std::task::Waker;
2/// The `Context` of an asynchronous task.
3///
4/// Unlike std::task::Context, this context *optionally* contains a waker.
5///
6/// This is necessary because try_send and try_recv need to poll,
7/// but the task waker should not be saved if the try returns pending.
8pub struct Context<'a> {
9    waker: Option<&'a Waker>,
10}
11
12impl<'a> From<std::task::Context<'a>> for Context<'a> {
13    fn from(cx: std::task::Context<'a>) -> Self {
14        Self::from_waker(cx.waker())
15    }
16}
17
18impl<'a> From<&std::task::Context<'a>> for Context<'a> {
19    fn from(cx: &std::task::Context<'a>) -> Self {
20        Self::from_waker(cx.waker())
21    }
22}
23
24impl<'a> From<&mut std::task::Context<'a>> for Context<'a> {
25    fn from(cx: &mut std::task::Context<'a>) -> Self {
26        Self::from_waker(cx.waker())
27    }
28}
29
30impl<'a> Context<'a> {
31    /// Create a new `Context` from a `&Waker`.
32    pub fn from_waker(waker: &'a Waker) -> Self {
33        Context { waker: Some(waker) }
34    }
35
36    /// Create an empty context with no waker.
37    pub fn empty() -> Self {
38        Self { waker: None }
39    }
40
41    /// Returns an optional reference to the `Waker` for the current task.
42    pub fn waker(&self) -> Option<&'a Waker> {
43        self.waker
44    }
45}
46
47impl std::fmt::Debug for Context<'_> {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        f.debug_struct("Context")
50            .field("waker", &self.waker)
51            .finish()
52    }
53}