Skip to main content

tuwunel_core/utils/set/
mod.rs

1//! Set operations on iterators and streams.
2//!
3//! Sorted variants require their inputs to be ascending under a total order
4//! and preserve multiplicity. The unsorted [`intersection`] runs in O(n*m)
5//! and is provided for convenience when sorting is unavailable.
6
7mod difference_sorted_stream2;
8mod intersection;
9mod intersection_sorted;
10mod intersection_sorted_stream2;
11
12use std::{pin::Pin, task::ready};
13
14use futures::{
15	Stream,
16	task::{Context, Poll},
17};
18
19pub use self::{
20	difference_sorted_stream2::difference_sorted_stream2, intersection::intersection,
21	intersection_sorted::intersection_sorted,
22	intersection_sorted_stream2::intersection_sorted_stream2,
23};
24
25/// Lazily fill the cached head of `stream` into `peeked` and return a borrow.
26///
27/// On entry, `Some(v)` in `peeked` is a previously-buffered head that has not
28/// yet been consumed; `None` means the head must be pulled from the stream.
29/// Returns `Ready(Some(&v))` when a head is available, `Ready(None)` once
30/// `stream` is exhausted, or `Pending` when waiting on the stream.
31fn poll_head<'p, S, T>(
32	stream: Pin<&mut S>,
33	peeked: &'p mut Option<T>,
34	cx: &mut Context<'_>,
35) -> Poll<Option<&'p T>>
36where
37	S: Stream<Item = T>,
38{
39	if peeked.is_none() {
40		*peeked = ready!(stream.poll_next(cx));
41	}
42
43	Poll::Ready(peeked.as_ref())
44}