Skip to main content

tuwunel_core/utils/future/
option_stream.rs

1use futures::{FutureExt, Stream, StreamExt, future::OptionFuture};
2
3use super::super::IterStream;
4
5/// Converts an optional future of initial and trailing items into a stream.
6///
7/// A present future yields its iterable items before chaining its trailing
8/// stream. An absent future becomes an empty stream.
9pub trait OptionStream<T> {
10	/// Flattens the optional future into one ordered stream.
11	///
12	/// Items from the returned iterable are emitted before the accompanying
13	/// stream is polled. No items are emitted when the optional future is
14	/// absent.
15	fn stream(self) -> impl Stream<Item = T> + Send;
16}
17
18impl<T, O, S, Fut> OptionStream<T> for OptionFuture<Fut>
19where
20	Fut: Future<Output = (O, S)> + Send,
21	S: Stream<Item = T> + Send,
22	O: IntoIterator<Item = T> + Send,
23	<O as IntoIterator>::IntoIter: Send,
24	T: Send,
25{
26	#[inline]
27	fn stream(self) -> impl Stream<Item = T> + Send {
28		self.map(|opt| opt.map(|(curr, next)| curr.into_iter().stream().chain(next)))
29			.map(Option::into_iter)
30			.map(IterStream::stream)
31			.flatten_stream()
32			.flatten()
33	}
34}