futures_async_runtime/
lib.rs1#![no_std]
2#![cfg_attr(feature = "nightly", feature(generator_trait))]
3#![cfg_attr(feature = "nightly", feature(on_unimplemented))]
4#![cfg_attr(feature = "nightly", feature(arbitrary_self_types))]
5#![cfg_attr(feature = "nightly", feature(optin_builtin_traits))]
6#![cfg_attr(feature = "nightly", feature(pin))]
7
8macro_rules! if_nightly_and_std {
9 ($($i:item)*) => ($(
10 #[cfg(all(feature = "nightly", feature = "std"))]
11 $i
12 )*)
13}
14
15#[cfg(all(feature = "nightly", feature = "std"))]
16#[macro_use]
17extern crate std;
18
19if_nightly_and_std! {
20 extern crate futures_core;
21 extern crate futures_stable;
22
23 mod future;
24 mod stream;
25
26 use std::cell::Cell;
27 use std::mem;
28 use std::ptr;
29 use futures_core::task;
30
31 pub use self::future::*;
32 pub use self::stream::*;
33
34 pub use futures_core::{Async, Future, Stream};
35 pub use futures_stable::{StableFuture, StableStream};
36
37 pub use std::ops::Generator;
38
39#[rustc_on_unimplemented = "async functions must return a `Result` or \
40 a typedef of `Result`"]
41 pub trait IsResult {
42 type Ok;
43 type Err;
44
45 fn into_result(self) -> Result<Self::Ok, Self::Err>;
46 }
47 impl<T, E> IsResult for Result<T, E> {
48 type Ok = T;
49 type Err = E;
50
51 fn into_result(self) -> Result<Self::Ok, Self::Err> { self }
52 }
53
54 pub fn diverge<T>() -> T { loop {} }
55
56 type StaticContext = *mut task::Context<'static>;
57
58 thread_local!(static CTX: Cell<StaticContext> = Cell::new(ptr::null_mut()));
59
60 struct Reset<'a>(StaticContext, &'a Cell<StaticContext>);
61
62 impl<'a> Reset<'a> {
63 fn new(ctx: &mut task::Context, cell: &'a Cell<StaticContext>) -> Reset<'a> {
64 let stored_ctx = unsafe { mem::transmute::<&mut task::Context, StaticContext>(ctx) };
65 let ctx = cell.replace(stored_ctx);
66 Reset(ctx, cell)
67 }
68
69 fn new_null(cell: &'a Cell<StaticContext>) -> Reset<'a> {
70 let ctx = cell.replace(ptr::null_mut());
71 Reset(ctx, cell)
72 }
73 }
74
75 impl<'a> Drop for Reset<'a> {
76 fn drop(&mut self) {
77 self.1.set(self.0);
78 }
79 }
80
81 pub fn in_ctx<F: FnOnce(&mut task::Context) -> T, T>(f: F) -> T {
82 CTX.with(|cell| {
83 let r = Reset::new_null(cell);
84 if r.0 == ptr::null_mut() {
85 panic!("Cannot use `await!`, `await_item!`, or `#[async] for` outside of an `async` function.")
86 }
87 f(unsafe { &mut *r.0 })
88 })
89 }
90}