rocket/util/
mod.rs

1mod chain;
2mod reader_stream;
3mod join;
4
5#[cfg(unix)]
6pub mod unix;
7
8pub use chain::Chain;
9pub use reader_stream::ReaderStream;
10pub use join::join;
11
12#[track_caller]
13pub fn spawn_inspect<E, F, Fut>(or: F, future: Fut)
14    where F: FnOnce(&E) + Send + Sync + 'static,
15          E: Send + Sync + 'static,
16        Fut: std::future::Future<Output = Result<(), E>> + Send + 'static,
17{
18    use futures::TryFutureExt;
19    tokio::spawn(future.inspect_err(or));
20}
21
22use std::{fmt, io};
23use std::pin::pin;
24use std::future::Future;
25use either::Either;
26use futures::future;
27
28pub trait FutureExt: Future + Sized {
29    /// Await `self` or `other`, whichever finishes first.
30    async fn race<B: Future>(self, other: B) -> Either<Self::Output, B::Output> {
31        match future::select(pin!(self), pin!(other)).await {
32            future::Either::Left((v, _)) => Either::Left(v),
33            future::Either::Right((v, _)) => Either::Right(v),
34        }
35    }
36
37    async fn race_io<T, K: Future>(self, trigger: K) -> io::Result<T>
38        where Self: Future<Output = io::Result<T>>
39    {
40        match future::select(pin!(self), pin!(trigger)).await {
41            future::Either::Left((v, _)) => v,
42            future::Either::Right((_, _)) => Err(io::Error::other("i/o terminated")),
43        }
44    }
45}
46
47impl<F: Future + Sized> FutureExt for F { }
48
49pub struct Formatter<F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result>(pub F);
50
51impl<F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result> fmt::Debug for Formatter<F> {
52    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53        (self.0)(f)
54    }
55}
56
57impl<F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result> fmt::Display for Formatter<F> {
58    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59        (self.0)(f)
60    }
61}
62
63#[doc(hidden)]
64#[macro_export]
65macro_rules! for_both {
66    ($value:expr, $pattern:pat => $result:expr) => {
67        match $value {
68            tokio_util::either::Either::Left($pattern) => $result,
69            tokio_util::either::Either::Right($pattern) => $result,
70        }
71    };
72}
73
74pub use for_both;