Skip to main content

tuwunel_core/utils/stream/
iter_stream.rs

1use futures::{
2	StreamExt, stream,
3	stream::{Stream, TryStream},
4};
5
6use crate::{Error, Result};
7
8/// Converts synchronous iterables into immediately ready streams.
9///
10/// Source iteration order is preserved. The fallible form wraps each item in a
11/// successful result using the crate's error type.
12pub trait IterStream<I: IntoIterator + Send> {
13	/// Converts the iterable into a stream of its items.
14	///
15	/// Items are yielded in the source iterator's order. Polling requires no
16	/// asynchronous work beyond advancing that iterator.
17	fn stream(self) -> impl Stream<Item = <I as IntoIterator>::Item> + Send;
18
19	/// Converts the iterable into a stream of successful results.
20	///
21	/// Every source item is wrapped in `Ok` with [`Error`] as the error type.
22	/// The adapter itself never produces an error.
23	fn try_stream(
24		self,
25	) -> impl TryStream<
26		Ok = <I as IntoIterator>::Item,
27		Error = Error,
28		Item = Result<<I as IntoIterator>::Item, Error>,
29	> + Send;
30}
31
32impl<I> IterStream<I> for I
33where
34	I: IntoIterator + Send,
35	<I as IntoIterator>::IntoIter: Send,
36{
37	#[inline]
38	fn stream(self) -> impl Stream<Item = <I as IntoIterator>::Item> + Send { stream::iter(self) }
39
40	#[inline]
41	fn try_stream(
42		self,
43	) -> impl TryStream<
44		Ok = <I as IntoIterator>::Item,
45		Error = Error,
46		Item = Result<<I as IntoIterator>::Item, Error>,
47	> + Send {
48		self.stream().map(Ok)
49	}
50}