Trait lending_iterator::LendingIterator
source · pub trait LendingIteratorwhere
Self: for<'next> LendingIteratorඞItem<'next>,{
Show 27 methods
// Required method
fn next(&mut self) -> Option<Item<'_, Self>>;
// Provided methods
fn filter<F>(self, should_yield: F) -> Filter<Self, F> ⓘ
where Self: Sized,
F: FnMut(&Item<'_, Self>) -> bool { ... }
fn for_each(self, f: impl FnMut(Item<'_, Self>))
where Self: Sized { ... }
fn fold<Acc>(
self,
acc: Acc,
f: impl FnMut(Acc, Item<'_, Self>) -> Acc
) -> Acc
where Self: Sized { ... }
fn try_for_each<Err>(
&mut self,
f: impl FnMut(Item<'_, Self>) -> Result<(), Err>
) -> Result<(), Err> { ... }
fn try_fold<Acc, Err>(
&mut self,
acc: Acc,
f: impl FnMut(Acc, Item<'_, Self>) -> Result<Acc, Err>
) -> Result<Acc, Err> { ... }
fn all(&mut self, predicate: impl FnMut(Item<'_, Self>) -> bool) -> bool
where Self: Sized { ... }
fn any(&mut self, predicate: impl FnMut(Item<'_, Self>) -> bool) -> bool
where Self: Sized { ... }
fn by_ref(&mut self) -> &mut Self ⓘ
where Self: Sized { ... }
fn count(self) -> usize
where Self: Sized { ... }
fn find<'find>(
&'find mut self,
predicate: impl 'find + FnMut(&Item<'_, Self>) -> bool
) -> Option<Item<'find, Self>>
where Self: Sized { ... }
fn fuse(self) -> Fuse<Self> ⓘ
where Self: Sized { ... }
fn nth(&mut self, n: usize) -> Option<Item<'_, Self>> { ... }
fn position<F>(
&mut self,
predicate: impl FnMut(Item<'_, Self>) -> bool
) -> Option<usize>
where Self: Sized { ... }
fn skip(self, count: usize) -> Skip<Self> ⓘ
where Self: Sized { ... }
fn take(self, count: usize) -> Take<Self> ⓘ
where Self: Sized { ... }
fn map<NewItemType: HKT, F>(self, f: F) -> Map<Self, F, NewItemType> ⓘ
where for<'next> F: FnMut([&'next Self; 0], Item<'next, Self>) -> Feed<'next, NewItemType>,
Self: Sized { ... }
fn map_to_ref<R: ?Sized, F>(self, f: F) -> Map<Self, F, HKTRef<R>> ⓘ
where for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> &'any R,
Self: Sized { ... }
fn map_to_mut<R: ?Sized, F>(self, f: F) -> Map<Self, F, HKTRefMut<R>> ⓘ
where for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> &'any mut R,
Self: Sized { ... }
fn map_into_iter<F, NonLendingItem>(self, f: F) -> MapIntoIter<Self, F> ⓘ
where F: FnMut(Item<'_, Self>) -> NonLendingItem,
Self: Sized { ... }
fn filter_map<NewItemType: HKT, F>(
self,
f: F
) -> FilterMap<Self, F, NewItemType> ⓘ
where for<'next> F: FnMut([&'next Self; 0], Item<'next, Self>) -> Option<Feed<'next, NewItemType>>,
Self: Sized { ... }
fn filter_map_to_ref<R: ?Sized, F>(
self,
f: F
) -> FilterMap<Self, F, HKTRef<R>> ⓘ
where for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> Option<&'any R>,
Self: Sized { ... }
fn filter_map_to_mut<R: ?Sized, F>(
self,
f: F
) -> FilterMap<Self, F, HKTRefMut<R>> ⓘ
where for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> Option<&'any mut R>,
Self: Sized { ... }
fn filter_map_into_iter<F, NonLendingItem>(
self,
f: F
) -> FilterMapIntoIter<Self, F> ⓘ
where F: FnMut(Item<'_, Self>) -> Option<NonLendingItem>,
Self: Sized { ... }
fn into_iter<Item>(self) -> IntoIter<Self> ⓘ
where Self: for<'any> LendingIteratorඞItem<'any, T = Item> + Sized { ... }
fn dyn_boxed<'usability>(
self
) -> Box<dyn LendingIteratorDyn<Item = HKTItem<Self>> + 'usability>
where Self: 'usability + Sized { ... }
fn dyn_boxed_auto<BoxedDynLendingIterator, Item: HKT>(
self
) -> BoxedDynLendingIterator
where Self: Sized + DynCoerce<BoxedDynLendingIterator, Item> { ... }
}
Expand description
The meat of the crate. Trait similar to Iterator
but for the return
type of the fn next(&'_ mut self)
method being allowed to depend on that
'_
.
Click to hide
-
That type is called the
Item<'_>
type, and is ageneric_associated_type
. -
That difference is crucial both in terms of signature complexity (as this crate’s API ought to prove 😅) and borrowing semantics.
Mainly, when yielded, such Item<'_>
is still &mut
borrowing *self
, so
it won’t be possible to further advance the iterator (or anything else,
for that matter), until the current item is no longer used.
That is: the Item<'_>
s yielded by a LendingIterator
cannot
coëxist!
-
this will thus impose serious usability limitations on it (e.g, no
.collect()
ing whatsoever, since collecting items, by definition, expects them to coëxist (within the collection)).-
For instance, there won’t be a
for item in iter {
sugar on these things, since thatfor
sugar currently only blesses the stdlibIterator
trait.That being said,
while let Some(item) = iter.next() {
works just as well, to be honest.
-
-
but the dual / other side of that API restriction is that it is way simpler / less constraining, for implementors, to implement this trait.
The canonical example illustrating this difference is
windows_mut()
, which is both an intuitive “iterator” we can think of, and yet something for which it is impossible to implementIterator
.
A Generic Associated Type
The core definition of this trait is thus:
-
ⓘ
#![feature(generic_associated_types)] trait LendingIterator { type Item<'next> where Self : 'next, ; fn next<'next> ( self: &'next mut Self, // <- `Self : 'next` indeed! ) -> Option<Self::Item<'next>> ; }
As you can see, it involves that more complex type Item
definition, which
is called a generic associated type (GAT for short), and, it currently
requires the nightly
-only feature(generic_associated_types)
.
–Then how come this crate can work on stable?— you may ask.
The answer is that (lifetime)-GATs can actually be emulated in stable Rust through some extra slightly convoluted hoops.
That’s why this crate uses those techniques (and the crate featuring them,
::nougat
), to achieve Stable Rust support:
-
#[::nougat::gat] // 👈 Add this and now It Just Works™ on stable. trait LendingIterator { type Item<'next> where Self : 'next, ; fn next<'next> ( self: &'next mut Self, ) -> Option<Self::Item<'next>> ; }
It does come with a few caveats, though: the LendingIterator::Item
item
is no longer really nameable, at least not directly.
-
The current implementation of
::nougat
uses a helper higher-order super-trait, calledfor<'any> LendingIteratorඞItem<'any>
, which has, itself, a non-generic associated type,::T
. That way,LendingIteratorඞItem<'next>::T
plays the role ofLendingIterator::Item<'next>
.BUT THIS MAY change within semver-compatible changes of
nougat
That’s why that path should never be used, directly, by downstream code.
The only reason I am even talking about it and not having it
#[doc(hidden)]
is that exposing it makes understanding the signatures of the adapters multiple order of magnitude easier.
Hence the following “rules”:
-
Use
Item<'_, I>
instead ofI::Item<'_>
.-
you could technically import the
Gat!
macro from the::nougat
crate, and then useGat!(I::Item<'_>)
(this is how this crate manages to defineItem
, for instance). But it seems less convenient than a type alias. -
within a
#[gat]
-annotatedtrait
orimpl
, most of the…::Item<'_>
mentions will automagically be amended by the macro (which is why the previous snippet works, despite its usage ofSelf::Item<'next>
).
-
-
If implementing the trait yourself, you need to apply
#[gat]
to theimpl
yourself. -
If reëxporting the trait yourself, you need to also apply
#[gat(Item)]
to theuse
statement as well, so people can implement the trait through the new path. -
LendingIterator
is not reallydyn
-friendly (although IIUC, withfeature(generic_associated_types)
it wouldn’t have been either).But you can use
dyn LendingIteratorDyn<Item = …> + …
instead, which has been designed withdyn
-friendlyness in mind 🙂.
Required Methods§
sourcefn next(&mut self) -> Option<Item<'_, Self>>
fn next(&mut self) -> Option<Item<'_, Self>>
Query the next()
Item
of this Self
iterator.
LendingIterator
counterpart of Iterator::next()
.
Provided Methods§
sourcefn filter<F>(self, should_yield: F) -> Filter<Self, F> ⓘwhere
Self: Sized,
F: FnMut(&Item<'_, Self>) -> bool,
fn filter<F>(self, should_yield: F) -> Filter<Self, F> ⓘwhere Self: Sized, F: FnMut(&Item<'_, Self>) -> bool,
LendingIterator
counterpart of Iterator::filter()
.
sourcefn for_each(self, f: impl FnMut(Item<'_, Self>))where
Self: Sized,
fn for_each(self, f: impl FnMut(Item<'_, Self>))where Self: Sized,
LendingIterator
counterpart of Iterator::for_each()
.
sourcefn fold<Acc>(self, acc: Acc, f: impl FnMut(Acc, Item<'_, Self>) -> Acc) -> Accwhere
Self: Sized,
fn fold<Acc>(self, acc: Acc, f: impl FnMut(Acc, Item<'_, Self>) -> Acc) -> Accwhere Self: Sized,
LendingIterator
counterpart of Iterator::fold()
.
sourcefn try_for_each<Err>(
&mut self,
f: impl FnMut(Item<'_, Self>) -> Result<(), Err>
) -> Result<(), Err>
fn try_for_each<Err>( &mut self, f: impl FnMut(Item<'_, Self>) -> Result<(), Err> ) -> Result<(), Err>
LendingIterator
counterpart of Iterator::try_for_each()
.
sourcefn try_fold<Acc, Err>(
&mut self,
acc: Acc,
f: impl FnMut(Acc, Item<'_, Self>) -> Result<Acc, Err>
) -> Result<Acc, Err>
fn try_fold<Acc, Err>( &mut self, acc: Acc, f: impl FnMut(Acc, Item<'_, Self>) -> Result<Acc, Err> ) -> Result<Acc, Err>
LendingIterator
counterpart of Iterator::try_fold()
.
sourcefn all(&mut self, predicate: impl FnMut(Item<'_, Self>) -> bool) -> boolwhere
Self: Sized,
fn all(&mut self, predicate: impl FnMut(Item<'_, Self>) -> bool) -> boolwhere Self: Sized,
LendingIterator
counterpart of Iterator::all()
.
sourcefn any(&mut self, predicate: impl FnMut(Item<'_, Self>) -> bool) -> boolwhere
Self: Sized,
fn any(&mut self, predicate: impl FnMut(Item<'_, Self>) -> bool) -> boolwhere Self: Sized,
LendingIterator
counterpart of Iterator::any()
.
sourcefn by_ref(&mut self) -> &mut Self ⓘwhere
Self: Sized,
fn by_ref(&mut self) -> &mut Self ⓘwhere Self: Sized,
LendingIterator
counterpart of Iterator::by_ref()
.
sourcefn count(self) -> usizewhere
Self: Sized,
fn count(self) -> usizewhere Self: Sized,
LendingIterator
counterpart of Iterator::count()
.
sourcefn find<'find>(
&'find mut self,
predicate: impl 'find + FnMut(&Item<'_, Self>) -> bool
) -> Option<Item<'find, Self>>where
Self: Sized,
fn find<'find>( &'find mut self, predicate: impl 'find + FnMut(&Item<'_, Self>) -> bool ) -> Option<Item<'find, Self>>where Self: Sized,
LendingIterator
counterpart of Iterator::find()
.
sourcefn fuse(self) -> Fuse<Self> ⓘwhere
Self: Sized,
fn fuse(self) -> Fuse<Self> ⓘwhere Self: Sized,
LendingIterator
counterpart of Iterator::fuse()
.
sourcefn nth(&mut self, n: usize) -> Option<Item<'_, Self>>
fn nth(&mut self, n: usize) -> Option<Item<'_, Self>>
LendingIterator
counterpart of Iterator::nth()
.
sourcefn position<F>(
&mut self,
predicate: impl FnMut(Item<'_, Self>) -> bool
) -> Option<usize>where
Self: Sized,
fn position<F>( &mut self, predicate: impl FnMut(Item<'_, Self>) -> bool ) -> Option<usize>where Self: Sized,
LendingIterator
counterpart of Iterator::position()
.
sourcefn skip(self, count: usize) -> Skip<Self> ⓘwhere
Self: Sized,
fn skip(self, count: usize) -> Skip<Self> ⓘwhere Self: Sized,
LendingIterator
counterpart of Iterator::skip()
.
sourcefn take(self, count: usize) -> Take<Self> ⓘwhere
Self: Sized,
fn take(self, count: usize) -> Take<Self> ⓘwhere Self: Sized,
LendingIterator
counterpart of Iterator::take()
.
sourcefn map<NewItemType: HKT, F>(self, f: F) -> Map<Self, F, NewItemType> ⓘwhere
for<'next> F: FnMut([&'next Self; 0], Item<'next, Self>) -> Feed<'next, NewItemType>,
Self: Sized,
fn map<NewItemType: HKT, F>(self, f: F) -> Map<Self, F, NewItemType> ⓘwhere for<'next> F: FnMut([&'next Self; 0], Item<'next, Self>) -> Feed<'next, NewItemType>, Self: Sized,
LendingIterator
counterpart of Iterator::map()
.
-
Turbofishing the
NewItemType
is mandatory, otherwise you’ll run into issues with non-higher-order closures.See the module-level documentation of
crate::higher_kinded_types
for more info.But the TL,DR is that you’d use it as:
lending_iter.map::<HKT!(ReturnType<'_>), _>(
-
the second idiosyncracy is that, for technical reasons1 related to the maximally generic aspect of this API, the closure itself cannot just be a
Self::Item<'_> -> Feed<'_, NewItemType>
closure, and instead, requires that an extra[]
dummy parameter be part of the signature:lending_iter.map::<HKT…, _>(|[], item| { … }) 👆
In the case where
Self::Item<'_>
does not depend on'_
, the return type then technically can’t depend on it either, so Rust complains about this (in a rather obtuse fashion). We solve this by requiring that extra[]
parameter which acts as a convenient-to-writePhantomData
which does depend on'_
. ↩
sourcefn map_to_ref<R: ?Sized, F>(self, f: F) -> Map<Self, F, HKTRef<R>> ⓘwhere
for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> &'any R,
Self: Sized,
fn map_to_ref<R: ?Sized, F>(self, f: F) -> Map<Self, F, HKTRef<R>> ⓘwhere for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> &'any R, Self: Sized,
sourcefn map_to_mut<R: ?Sized, F>(self, f: F) -> Map<Self, F, HKTRefMut<R>> ⓘwhere
for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> &'any mut R,
Self: Sized,
fn map_to_mut<R: ?Sized, F>(self, f: F) -> Map<Self, F, HKTRefMut<R>> ⓘwhere for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> &'any mut R, Self: Sized,
sourcefn map_into_iter<F, NonLendingItem>(self, f: F) -> MapIntoIter<Self, F> ⓘwhere
F: FnMut(Item<'_, Self>) -> NonLendingItem,
Self: Sized,
fn map_into_iter<F, NonLendingItem>(self, f: F) -> MapIntoIter<Self, F> ⓘwhere F: FnMut(Item<'_, Self>) -> NonLendingItem, Self: Sized,
Convenience shorthand for
.map…(…).into_iter()
.
When the return type of the .map()
closure is not lending
/ borrowing from *self
, it becomes possible to call
.into_iter() on it right away.
Moreover, it makes the [],
closure arg hack no longer necessary.
This convenience function encompasses both things, thence returning
an Iterator
(not a LendingIterator
!).
sourcefn filter_map<NewItemType: HKT, F>(
self,
f: F
) -> FilterMap<Self, F, NewItemType> ⓘwhere
for<'next> F: FnMut([&'next Self; 0], Item<'next, Self>) -> Option<Feed<'next, NewItemType>>,
Self: Sized,
fn filter_map<NewItemType: HKT, F>( self, f: F ) -> FilterMap<Self, F, NewItemType> ⓘwhere for<'next> F: FnMut([&'next Self; 0], Item<'next, Self>) -> Option<Feed<'next, NewItemType>>, Self: Sized,
LendingIterator
counterpart of Iterator::filter_map()
.
All the caveats and remarks of .map()
apply, go check
them up.
sourcefn filter_map_to_ref<R: ?Sized, F>(self, f: F) -> FilterMap<Self, F, HKTRef<R>> ⓘwhere
for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> Option<&'any R>,
Self: Sized,
fn filter_map_to_ref<R: ?Sized, F>(self, f: F) -> FilterMap<Self, F, HKTRef<R>> ⓘwhere for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> Option<&'any R>, Self: Sized,
Convenience method: same as
.filter_map()
, but for hard-coding the
HKT
parameter to HKTRef<R> = HKT!(&R)
.
All the caveats and remarks of
.map_to_ref()
apply, go check them up.
sourcefn filter_map_to_mut<R: ?Sized, F>(
self,
f: F
) -> FilterMap<Self, F, HKTRefMut<R>> ⓘwhere
for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> Option<&'any mut R>,
Self: Sized,
fn filter_map_to_mut<R: ?Sized, F>( self, f: F ) -> FilterMap<Self, F, HKTRefMut<R>> ⓘwhere for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> Option<&'any mut R>, Self: Sized,
Convenience method: same as
.filter_map()
, but for hard-coding the
HKT
parameter to HKTRefMut<R> = HKT!(&mut R)
.
All the caveats and remarks of
.map_to_mut()
apply, go check them up.
sourcefn filter_map_into_iter<F, NonLendingItem>(
self,
f: F
) -> FilterMapIntoIter<Self, F> ⓘwhere
F: FnMut(Item<'_, Self>) -> Option<NonLendingItem>,
Self: Sized,
fn filter_map_into_iter<F, NonLendingItem>( self, f: F ) -> FilterMapIntoIter<Self, F> ⓘwhere F: FnMut(Item<'_, Self>) -> Option<NonLendingItem>, Self: Sized,
Convenience shorthand for
.filter_map…(…).into_iter()
.
When the return type of the .filter_map()
closure is not lending
/ borrowing from *self
, it becomes possible to call
.into_iter() on it right away.
Moreover, it makes the [],
closure arg hack no longer necessary.
This convenience function encompasses both things, thence returning
an Iterator
(not a LendingIterator
!).
sourcefn into_iter<Item>(self) -> IntoIter<Self> ⓘwhere
Self: for<'any> LendingIteratorඞItem<'any, T = Item> + Sized,
fn into_iter<Item>(self) -> IntoIter<Self> ⓘwhere Self: for<'any> LendingIteratorඞItem<'any, T = Item> + Sized,
Convert a Self : LendingIterator
into an Iterator
,
provided Self::Item<'_>
does not depend on '_
.
sourcefn dyn_boxed<'usability>(
self
) -> Box<dyn LendingIteratorDyn<Item = HKTItem<Self>> + 'usability>where
Self: 'usability + Sized,
fn dyn_boxed<'usability>( self ) -> Box<dyn LendingIteratorDyn<Item = HKTItem<Self>> + 'usability>where Self: 'usability + Sized,
alloc
only.Converts this LendingIterator
into a
Box<dyn LendingIteratorDyn…>
.
Note that the return dyn Trait
will not be Send
or implement any
other auto-traits. For a more general albeit harder-on-type-inference
alternative, see .dyn_boxed_auto()
.
sourcefn dyn_boxed_auto<BoxedDynLendingIterator, Item: HKT>(
self
) -> BoxedDynLendingIteratorwhere
Self: Sized + DynCoerce<BoxedDynLendingIterator, Item>,
fn dyn_boxed_auto<BoxedDynLendingIterator, Item: HKT>( self ) -> BoxedDynLendingIteratorwhere Self: Sized + DynCoerce<BoxedDynLendingIterator, Item>,
alloc
only.Converts this LendingIterator
into a
Box<dyn LendingIteratorDyn…>
.
In order for it to work, the Item
parameter has to be provided
(probably funneled through a CanonicalHKT
), as well as an explicit
“landing type” (inference will probably fail to figure it out!).
That is, BoxedDynLendingIterator
is expected to be of the form:
Box<dyn 'lt [+ Send] [+ Sync] + LendingIteratorDyn<Item = CanonicalHKT<…>>>
Implementations on Foreign Types§
source§impl<I: ?Sized + LendingIterator> LendingIterator for Box<I>
Available on crate feature alloc
only.
impl<I: ?Sized + LendingIterator> LendingIterator for Box<I>
alloc
only.source§impl<'r, I: ?Sized + LendingIterator> LendingIterator for &'r mut I
impl<'r, I: ?Sized + LendingIterator> LendingIterator for &'r mut I
source§impl<I> LendingIterator for Pin<Box<I>>where
I: Unpin + ?Sized + LendingIterator,
Available on crate feature alloc
only.
impl<I> LendingIterator for Pin<Box<I>>where I: Unpin + ?Sized + LendingIterator,
alloc
only.source§impl<'r, I> LendingIterator for Pin<&'r mut I>where
I: Unpin + ?Sized + LendingIterator,
impl<'r, I> LendingIterator for Pin<&'r mut I>where I: Unpin + ?Sized + LendingIterator,
Implementors§
impl<'lt, T, const WINDOW_SIZE: usize> LendingIterator for WindowsMut<&'lt mut [T], WINDOW_SIZE>
impl<'usability, Item: HKT> LendingIterator for dyn LendingIteratorDyn<Item = Item> + 'usability
dyn LendingIteratorDyn + … : LendingIterator
impl<'usability, Item: HKT> LendingIterator for dyn LendingIteratorDyn<Item = Item> + Send + 'usability
dyn LendingIteratorDyn + … : LendingIterator
impl<'usability, Item: HKT> LendingIterator for dyn LendingIteratorDyn<Item = Item> + Send + Sync + 'usability
dyn LendingIteratorDyn + … : LendingIterator
impl<'usability, Item: HKT> LendingIterator for dyn LendingIteratorDyn<Item = Item> + Sync + 'usability
dyn LendingIteratorDyn + … : LendingIterator
impl<I, F> LendingIterator for Filter<I, F>where I: LendingIterator, F: FnMut(&Item<'_, I>) -> bool,
impl<I, NewItemType, F> LendingIterator for FilterMap<I, F, NewItemType>where I: LendingIterator, NewItemType: HKT, for<'any> F: FnMut([&'any I; 0], Item<'any, I>) -> Option<Feed<'any, NewItemType>>,
impl<I, NewItemType, F> LendingIterator for Map<I, F, NewItemType>where I: LendingIterator, NewItemType: HKT, for<'any> F: FnMut([&'any I; 0], Item<'any, I>) -> Feed<'any, NewItemType>,
impl<I: LendingIterator> LendingIterator for Fuse<I>
impl<I: LendingIterator> LendingIterator for Skip<I>
impl<I: LendingIterator> LendingIterator for Take<I>
impl<I: ?Sized + Iterator> LendingIterator for FromIter<I>
impl<Item, State, Next> LendingIterator for FromFn<Item, State, Next>where Item: HKT, Next: FnMut(&mut State) -> Option<Feed<'_, Item>>,
impl<S: Stream + Unpin> LendingIterator for FromStream<S>
futures
only.