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