Expand description
§::lending-iterator
Fully generic LendingIterators in stable Rust.
-
this pattern used to be called
StreamingIterator, but sinceStreams entered the picture (as theasync/.awaitversion ofIterators, that is,AsyncIterators), it has been deemed more suitable to go for the lending naming convention.- (this could be even more relevant since you can have a
LendingIteratorlendingimpl Futures, which would effectively make it another flavor ofAsyncIterator, but not quite theStreamvariant).
- (this could be even more relevant since you can have a
-
For context, this crate is a generalization of other crates such as:
which hard-code their lending
Itemtype to&_andResult<&_, _>respectively.This crate does not hardcode such dependent types, and thus encompasses both of those traits, and infinitely more!
-
Mainly, it allows lending
&mut _Items, which means it can handle the infamously challengingwindows_mut()pattern!
§Examples
Click to hide
§windows_mut()!
use ::lending_iterator::prelude::*;
let mut array = [0; 15];
array[1] = 1;
// Cumulative sums are trivial with a `mut` sliding window,
// so let's showcase that by generating a Fibonacci sequence.
let mut iter = array.windows_mut::<3>();
while let Some(&mut [a, b, ref mut next]) = iter.next() {
*next = a + b;
}
assert_eq!(
array,
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377],
);§Rolling your own version of it using the handy from_fn constructor
- (Or even the
FromFnflavor of it to enjoy “named arguments”)
use ::lending_iterator::prelude::*;
let mut array = [0; 15];
array[1] = 1;
// Let's hand-roll our iterator lending `&mut` sliding windows:
let mut iter = {
let mut start = 0;
lending_iterator::FromFn::<HKT!(&mut [u16; 3]), _, _> {
state: &mut array,
next: move |array| {
let to_yield =
array
.get_mut(start..)?
.get_mut(..3)?
.try_into() // `&mut [u8] -> &mut [u8; 3]`
.unwrap()
;
start += 1;
Some(to_yield)
},
_phantom: <_>::default(),
}
};
while let Some(&mut [a, b, ref mut next]) = iter.next() {
*next = a + b;
}
assert_eq!(
array,
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377],
);-
where that
HKT!(&mut [u16; 3])is a higher-kinded type parameter that has to be turbofished to let the generic context properly figure out the return type of thenextclosure.Indeed, if we were to let type inference, alone, figure it out, it wouldn’t be able to know which lifetimes would be fixed/tied to call-site captures, and which would be tied to the “lending-ness” of the iterator (higher-order return type). See
::higher-order-closurefor more info about this.
§LendingIterator adapters
See lending_iterator::adapters.
§Bonus: Higher-Kinded Types (HKT)
See higher_kinded_types for a presentation about them.
§Real-life usage: .sort_by_key() that is fully generic over the key lending mode
As noted in this 6-year-old issue:
Such an API can easily be provided using the HKT API of this crate:
Click to show
use ::lending_iterator::higher_kinded_types::{*, Apply as A};
fn slice_sort_by_key<Key, Item, KeyGetter> (
slice: &'_ mut [Item],
mut get_key: KeyGetter,
)
where
Key : HKT, // "Key : <'_>"
KeyGetter : for<'item> FnMut(&'item Item) -> A!(Key<'item>),
for<'item>
A!(Key<'item>) : Ord
,
{
slice.sort_by(|a, b| Ord::cmp(
&get_key(a),
&get_key(b),
))
}
// ---- Demo ----
struct Client { key: String, version: u8 }
fn main ()
{
let clients: &mut [Client] = &mut [];
// Error: cannot infer an appropriate lifetime for autoref due to conflicting requirements
// clients.sort_by_key(|c| &c.key);
// OK
slice_sort_by_key::<HKT!(&str), _, _>(clients, |c| &c.key);
// Important: owned case works too!
slice_sort_by_key::<HKT!(u8), _, _>(clients, |c| c.version);
}Modules§
- higher_
kinded_ types - Helper traits and types to work with some of the more advanced higher-order APIs.
- lending_
iterator - Trait and helper adapter definitions.
- prelude
- The crate’s prelude.
Macros§
Structs§
- FromFn
- The
impl LendingIteratorreturned byfrom_fn().
Traits§
- Lending
Iterator - The meat of the crate. Trait similar to
Iteratorbut for the return type of thefn next(&'_ mut self)method being allowed to depend on that'_.
Functions§
- from_fn
- Main ad-hoc / closure-based constructor of
LendingIterators. - from_
iter - “Lifts” / converts an [
Into]Iteratorinto animpl LendingIterator - from_
stream futures - “Lifts” and converts an
UnpinStreaminto animpl LendingIteratorwhich lends futures (anS, say). - repeat_
mut - Returns an infinite
impl LendingIteratorwhich lends&'next mut Stateitems. - windows_
mut - Creates an
impl LendingIteratorover the sliding windows of a slice, with&mut/ exclusive access over them (yields&mut [T]slices).