Skip to content

Commit

Permalink
Merge pull request #18 from ratmice/lending_refs
Browse files Browse the repository at this point in the history
add `into_lending_refs` and `into_lending_refs_mut`
  • Loading branch information
Crazytieguy authored Dec 5, 2023
2 parents df6b3db + 7ab9acc commit 74821af
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 1 deletion.
55 changes: 55 additions & 0 deletions src/to_lending/lend_refs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use crate::LendingIterator;

/// A lending iterator that given an iterator, lends
/// references to the given iterator's items.
pub struct LendRefs<I: Iterator> {
item: Option<I::Item>,
iter: I,
}

impl<I: Iterator> LendRefs<I> {
pub(crate) fn new(iter: I) -> LendRefs<I> {
LendRefs { item: None, iter }
}
}

impl<I> LendingIterator for LendRefs<I>
where
I: Iterator,
{
type Item<'a> = &'a I::Item where Self: 'a;

fn next(&mut self) -> Option<Self::Item<'_>> {
self.item = self.iter.next();
self.item.as_ref()
}
}
#[cfg(test)]
mod test {
use crate::{LendingIterator, ToLendingIterator};
#[derive(Clone, Eq, PartialEq, Debug)]
struct Foo(usize);
struct W {
x: Foo,
}
impl LendingIterator for W {
type Item<'a> = &'a Foo where Self: 'a;
fn next(&mut self) -> Option<Self::Item<'_>> {
self.x.0 += 1;
Some(&self.x)
}
}
#[test]
fn test() {
let mut xs = Vec::new();
test_helper().take(3).for_each(|x: &Foo| {
xs.push(x.clone());
});
assert_eq!(xs, vec![Foo(0), Foo(1), Foo(2)]);
}

fn test_helper() -> impl for<'a> LendingIterator<Item<'a> = &'a Foo> {
let w = W { x: Foo(0) };
std::iter::once(Foo(0)).lend_refs().chain(w)
}
}
56 changes: 56 additions & 0 deletions src/to_lending/lend_refs_mut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use crate::LendingIterator;

/// A lending iterator that given an iterator, lends
/// mutable references to the given iterator's items.
pub struct LendRefsMut<I: Iterator> {
item: Option<I::Item>,
iter: I,
}

impl<I: Iterator> LendRefsMut<I> {
pub(crate) fn new(iter: I) -> LendRefsMut<I> {
LendRefsMut { item: None, iter }
}
}

impl<I: Iterator> LendingIterator for LendRefsMut<I> {
type Item<'a> = &'a mut I::Item where Self: 'a;

fn next(&mut self) -> Option<Self::Item<'_>> {
self.item = self.iter.next();
self.item.as_mut()
}
}

#[cfg(test)]
mod test {
use crate::{LendingIterator, ToLendingIterator};
#[derive(Clone, Eq, PartialEq, Debug)]
struct Foo(usize);
struct W {
x: Foo,
}

impl LendingIterator for W {
type Item<'a> = &'a mut Foo where Self: 'a;
fn next(&mut self) -> Option<Self::Item<'_>> {
self.x.0 += 1;
Some(&mut self.x)
}
}

#[test]
fn test() {
let mut xs = Vec::new();
test_helper().take(3).for_each(|x: &mut Foo| {
x.0 += 2;
xs.push(x.clone());
});
assert_eq!(xs, vec![Foo(2), Foo(3), Foo(6)]);
}

fn test_helper() -> impl for<'a> LendingIterator<Item<'a> = &'a mut Foo> {
let w = W { x: Foo(0) };
std::iter::once(Foo(0)).lend_refs_mut().chain(w)
}
}
4 changes: 4 additions & 0 deletions src/to_lending/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
mod into_lending;
mod lend_refs;
mod lend_refs_mut;
mod windows;
mod windows_mut;
pub use self::into_lending::IntoLending;
pub use self::lend_refs::LendRefs;
pub use self::lend_refs_mut::LendRefsMut;
pub use self::windows::Windows;
pub use self::windows_mut::WindowsMut;
20 changes: 19 additions & 1 deletion src/traits/to_lending_iterator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{IntoLending, Windows, WindowsMut};
use crate::{IntoLending, LendRefs, LendRefsMut, Windows, WindowsMut};

/// An extension trait for iterators that allows turning them into lending iterators (over windows of elements).
pub trait ToLendingIterator: IntoIterator {
Expand Down Expand Up @@ -35,6 +35,24 @@ pub trait ToLendingIterator: IntoIterator {
{
IntoLending::new(self.into_iter())
}

/// Turns this iterator into a lending iterator that lends references
/// to the iterator's items.
fn lend_refs(self) -> LendRefs<Self::IntoIter>
where
Self: Sized,
{
LendRefs::new(self.into_iter())
}

/// Turns this iterator into a lending iterator that lends mutable references
/// to the iterator's items.
fn lend_refs_mut(self) -> LendRefsMut<Self::IntoIter>
where
Self: Sized,
{
LendRefsMut::new(self.into_iter())
}
}

impl<I: IntoIterator> ToLendingIterator for I {}

0 comments on commit 74821af

Please sign in to comment.