2024-08-08 17:18:30 +00:00
|
|
|
//! Synchronous combinator extensions to futures::Stream
|
2024-10-27 00:30:30 +00:00
|
|
|
#![allow(clippy::type_complexity)]
|
2024-08-08 17:18:30 +00:00
|
|
|
|
|
|
|
use futures::{
|
|
|
|
future::{ready, Ready},
|
2024-09-30 06:46:54 +00:00
|
|
|
stream::{Any, Filter, FilterMap, Fold, ForEach, Scan, SkipWhile, Stream, StreamExt, TakeWhile},
|
2024-08-08 17:18:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Synchronous combinators to augment futures::StreamExt. Most Stream
|
|
|
|
/// combinators take asynchronous arguments, but often only simple predicates
|
|
|
|
/// are required to steer a Stream like an Iterator. This suite provides a
|
|
|
|
/// convenience to reduce boilerplate by de-cluttering non-async predicates.
|
|
|
|
///
|
|
|
|
/// This interface is not necessarily complete; feel free to add as-needed.
|
2024-09-30 06:46:54 +00:00
|
|
|
pub trait ReadyExt<Item>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
Self: Stream<Item = Item> + Send + Sized,
|
2024-08-08 17:18:30 +00:00
|
|
|
{
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_any<F>(self, f: F) -> Any<Self, Ready<bool>, impl FnMut(Item) -> Ready<bool>>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: Fn(Item) -> bool;
|
2024-08-08 17:18:30 +00:00
|
|
|
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_filter<'a, F>(self, f: F) -> Filter<Self, Ready<bool>, impl FnMut(&Item) -> Ready<bool> + 'a>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: Fn(&Item) -> bool + 'a;
|
2024-08-08 17:18:30 +00:00
|
|
|
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_filter_map<F, U>(self, f: F) -> FilterMap<Self, Ready<Option<U>>, impl FnMut(Item) -> Ready<Option<U>>>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: Fn(Item) -> Option<U>;
|
2024-08-08 17:18:30 +00:00
|
|
|
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_fold<T, F>(self, init: T, f: F) -> Fold<Self, Ready<T>, T, impl FnMut(T, Item) -> Ready<T>>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: Fn(T, Item) -> T;
|
2024-08-08 17:18:30 +00:00
|
|
|
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_for_each<F>(self, f: F) -> ForEach<Self, Ready<()>, impl FnMut(Item) -> Ready<()>>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: FnMut(Item);
|
2024-08-08 17:18:30 +00:00
|
|
|
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_take_while<'a, F>(self, f: F) -> TakeWhile<Self, Ready<bool>, impl FnMut(&Item) -> Ready<bool> + 'a>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: Fn(&Item) -> bool + 'a;
|
2024-08-08 17:18:30 +00:00
|
|
|
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_scan<B, T, F>(
|
|
|
|
self, init: T, f: F,
|
|
|
|
) -> Scan<Self, T, Ready<Option<B>>, impl FnMut(&mut T, Item) -> Ready<Option<B>>>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: Fn(&mut T, Item) -> Option<B>;
|
|
|
|
|
|
|
|
fn ready_scan_each<T, F>(
|
|
|
|
self, init: T, f: F,
|
|
|
|
) -> Scan<Self, T, Ready<Option<Item>>, impl FnMut(&mut T, Item) -> Ready<Option<Item>>>
|
|
|
|
where
|
|
|
|
F: Fn(&mut T, &Item);
|
|
|
|
|
|
|
|
fn ready_skip_while<'a, F>(self, f: F) -> SkipWhile<Self, Ready<bool>, impl FnMut(&Item) -> Ready<bool> + 'a>
|
|
|
|
where
|
|
|
|
F: Fn(&Item) -> bool + 'a;
|
2024-08-08 17:18:30 +00:00
|
|
|
}
|
|
|
|
|
2024-09-30 06:46:54 +00:00
|
|
|
impl<Item, S> ReadyExt<Item> for S
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
S: Stream<Item = Item> + Send + Sized,
|
2024-08-08 17:18:30 +00:00
|
|
|
{
|
|
|
|
#[inline]
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_any<F>(self, f: F) -> Any<Self, Ready<bool>, impl FnMut(Item) -> Ready<bool>>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: Fn(Item) -> bool,
|
2024-08-08 17:18:30 +00:00
|
|
|
{
|
|
|
|
self.any(move |t| ready(f(t)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_filter<'a, F>(self, f: F) -> Filter<Self, Ready<bool>, impl FnMut(&Item) -> Ready<bool> + 'a>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: Fn(&Item) -> bool + 'a,
|
2024-08-08 17:18:30 +00:00
|
|
|
{
|
|
|
|
self.filter(move |t| ready(f(t)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_filter_map<F, U>(self, f: F) -> FilterMap<Self, Ready<Option<U>>, impl FnMut(Item) -> Ready<Option<U>>>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: Fn(Item) -> Option<U>,
|
2024-08-08 17:18:30 +00:00
|
|
|
{
|
|
|
|
self.filter_map(move |t| ready(f(t)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_fold<T, F>(self, init: T, f: F) -> Fold<Self, Ready<T>, T, impl FnMut(T, Item) -> Ready<T>>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: Fn(T, Item) -> T,
|
2024-08-08 17:18:30 +00:00
|
|
|
{
|
|
|
|
self.fold(init, move |a, t| ready(f(a, t)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
#[allow(clippy::unit_arg)]
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_for_each<F>(self, mut f: F) -> ForEach<Self, Ready<()>, impl FnMut(Item) -> Ready<()>>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: FnMut(Item),
|
2024-08-08 17:18:30 +00:00
|
|
|
{
|
|
|
|
self.for_each(move |t| ready(f(t)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_take_while<'a, F>(self, f: F) -> TakeWhile<Self, Ready<bool>, impl FnMut(&Item) -> Ready<bool> + 'a>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: Fn(&Item) -> bool + 'a,
|
2024-08-08 17:18:30 +00:00
|
|
|
{
|
|
|
|
self.take_while(move |t| ready(f(t)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2024-09-30 06:46:54 +00:00
|
|
|
fn ready_scan<B, T, F>(
|
|
|
|
self, init: T, f: F,
|
|
|
|
) -> Scan<Self, T, Ready<Option<B>>, impl FnMut(&mut T, Item) -> Ready<Option<B>>>
|
|
|
|
where
|
|
|
|
F: Fn(&mut T, Item) -> Option<B>,
|
|
|
|
{
|
|
|
|
self.scan(init, move |s, t| ready(f(s, t)))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn ready_scan_each<T, F>(
|
|
|
|
self, init: T, f: F,
|
|
|
|
) -> Scan<Self, T, Ready<Option<Item>>, impl FnMut(&mut T, Item) -> Ready<Option<Item>>>
|
|
|
|
where
|
|
|
|
F: Fn(&mut T, &Item),
|
|
|
|
{
|
|
|
|
self.ready_scan(init, move |s, t| {
|
|
|
|
f(s, &t);
|
|
|
|
Some(t)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn ready_skip_while<'a, F>(self, f: F) -> SkipWhile<Self, Ready<bool>, impl FnMut(&Item) -> Ready<bool> + 'a>
|
2024-08-08 17:18:30 +00:00
|
|
|
where
|
2024-09-30 06:46:54 +00:00
|
|
|
F: Fn(&Item) -> bool + 'a,
|
2024-08-08 17:18:30 +00:00
|
|
|
{
|
|
|
|
self.skip_while(move |t| ready(f(t)))
|
|
|
|
}
|
|
|
|
}
|