Skip to main content

traffic_light/
future.rs

1//! Extension trait for [`Future`].
2//!
3//! # Examples
4//!
5//! ```
6//! use std::{error,result};
7//!
8//! use traffic_light::future::FutureExt as _;
9//!
10//! fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
11//!     async {
12//!         // ...
13//!         Ok::<(), Box<dyn std::error::Error>>(())
14//!     }.block_on()?;
15//!
16//!     Ok(())
17//! }
18//! ```
19
20use crate::executor::Executor;
21
22/// An extension trait for [`Future`] that provides blocking.
23pub trait FutureExt: Future {
24    /// Blocks the current thread on this future.
25    ///
26    /// # Panics
27    ///
28    /// Panics if this future panics.
29    ///
30    /// # Examples
31    ///
32    /// ```
33    /// # use std::{error,result};
34    /// #
35    /// use traffic_light::future::FutureExt as _;
36    ///
37    /// # fn main() -> result::Result<(), Box<dyn error::Error>> {
38    /// let x: result::Result<(), Box<dyn error::Error>> =
39    ///     async {
40    ///         // ...
41    ///         Ok(())
42    ///     }.block_on();
43    ///
44    /// assert!(x.is_ok());
45    /// #
46    /// #     Ok(())
47    /// # }
48    /// ```
49    fn block_on(self) -> Self::Output;
50}
51
52impl<F: Future> FutureExt for F {
53    fn block_on(self) -> Self::Output {
54        Executor::block_on(self)
55    }
56}
57
58#[rustfmt::skip]
59#[cfg(test)]
60mod tests {
61    use std::{error, result};
62
63    use super::*;
64
65    #[test]
66    fn block_on_result_ok() {
67        let x: result::Result<(), Box<dyn error::Error>> =
68            async {
69                Ok(())
70            }.block_on();
71
72        assert!(x.is_ok());
73    }
74
75    #[test]
76    fn block_on_result_err() {
77        let x: result::Result<(), &str> =
78            async {
79                Err("")
80            }.block_on();
81
82        assert!(x.is_err());
83    }
84}