1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//! Core primitives for building asynchronous stuff
//!
//! # This is [**Proposal A**](https://github.com/icorderi/rust-await/tree/proposal/a)
//!
//! This prposal is based on the idea of adding a single `Await` trait to the core.
//! The `Await` trait would provide a common abstraction over things that we could **resume** from.
//!
//! In the following example (with compiler support):
//!
//! ```ignore
//! pub **async** fn my_code() {
//!     // code block A
//!     let x = **await** some_func()
//!     // code block B
//! }
//! ```
//!
//! the expectation is that _"code block B"_ will be _resumed_ whenever the `await`'ing of `some_func` returns.
//!
//! For now, without compiler support, it would look like:
//!
//! ```ignore
//! pub fn my_code() {
//!     // code block A
//!     let x = some_func().await()
//!     // code block B
//! }
//! ```

pub mod examples;

pub mod io;

mod sync;
mod thread;
mod net;
mod fs;

pub use sync::*;
pub use thread::*;
pub use net::*;
pub use fs::*;

/// Represents then notion of something that we **could** have to _await_ for.
///
/// The keyword **await** _could_ be added to the language.
pub trait Await<T> {
    /// It will return a value when it's ready
    fn await(self) -> T;
}

/// `AwaitBox` is a version of the `Await` intended for use with _boxed_
/// objects.
///
/// The idea is that where one would normally store a
/// `Box<Await<T>>` in a data structure, you should use
/// `Box<AwaitBox<T>>`. The two traits behave essentially the same, except
/// that a `AwaitBox` can **only** be called if it is _boxed_.
///
/// > Note that `AwaitBox` may be deprecated in the future if `Box<Await<T>>`
/// become directly usable.
pub trait AwaitBox<T> {
    fn await_box(self: Box<Self>) -> T;
}

impl<T, A> AwaitBox<T> for A
    where A: Await<T>
{
    fn await_box(self: Box<Self>) -> T {
        self.await()
    }
}

impl<'a, T> Await<T> for Box<AwaitBox<T> + 'a> {
    fn await(self) -> T {
        self.await_box()
    }
}

impl<'a, T> Await<T> for Box<AwaitBox<T> + Send + 'a> {
    fn await(self) -> T {
        self.await_box()
    }
}

/// When they need an `Await<T>` and there is no need to wait
pub struct AwaitValue<T>(pub T);

impl<T> Await<T> for AwaitValue<T> {
    fn await(self) -> T {
        self.0
    }
}

// ============================================================================
//      `Await` for std types
// ============================================================================

// // `Await` on `Fn`
// impl<T, F: Fn() -> T> Await<T> for F {
//     fn await(self) -> T {
//         self()
//     }
// }

// `Await` on `FnOnce`
impl<T, F: FnOnce() -> T> Await<T> for F {
    fn await(self) -> T {
        self()
    }
}

#[cfg(test)]
mod tests {
    use std::thread;
    use Await;

    #[test]
    fn await_fn() {
        let x = || 8;
        assert_eq!(8, x.await());
    }

    #[test]
    fn await_thread() {
        let t = thread::spawn(|| 8);
        assert_eq!(8, t.await().unwrap());
    }

    #[test]
    fn await_box() {
        let x = Box::new(|| 8);
        assert_eq!(8, x.await());
    }
}