Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve docs on how to implement LendingIterator #9

Open
jorgecarleitao opened this issue Sep 23, 2022 · 2 comments
Open

Improve docs on how to implement LendingIterator #9

jorgecarleitao opened this issue Sep 23, 2022 · 2 comments

Comments

@jorgecarleitao
Copy link

The README describes how to implement anonymous implementations of LendingIterator. Would it be possible to expand a bit and demo how to implement a non-anonymous version?

I.e. given

struct ItemRef<'a>(&'a [u8]);
struct A(Vec<u8>);

how would

impl LendingIterator<ItemRef> for A

look like if say we want to return chunks of size 8 of the Vec<u8>

Thanks for the cool crate!

@Qqwy
Copy link

Qqwy commented Jan 13, 2023

Curiously there is an example in the documentation of the Nougat crate

#[macro_use]
extern crate nougat;

#[gat]
trait LendingIterator {
    type Item<'next>
    where
        Self : 'next,
    ;

    fn next(&mut self) -> Option<Self::Item<'_>>;
}

struct WindowsMut<Slice, const SIZE: usize> {
    slice: Slice,
    start: usize,
}

#[gat]
impl<Item, const SIZE: usize> LendingIterator for WindowsMut<&mut [Item], SIZE> {
    type Item<'next>
    where
        Self : 'next,
    =
        &'next mut [Item; SIZE]
    ;

    fn next(&mut self) -> Option<&mut [Item; SIZE]> {
        let to_yield =
            self.slice
                .get_mut(self.start ..)?
                .get_mut(.. SIZE)?
                .try_into()
                .expect("slice has the right SIZE")
        ;
        self.start += 1;
        Some(to_yield)
    }
}

@obskyr
Copy link

obskyr commented May 1, 2024

I attempted to find documentation on how to impl LendingIterator, but found nothing but @Qqwy's comment – but it's not helping much. I'm trying to create an iterator that offers slice windows into a buffer owned by the iterator itself, and I figured a lending iterator would be the right tool for the job. I seem to be getting the same errors as with a regular Iterator, however… Here's a minimal example:

use ::lending_iterator::prelude::*;

struct Slicer<'a> {
    full: Vec<u32>,
    cur_slice: &'a mut [u32]
}

impl<'a> Slicer<'a> {
    fn new() -> Slicer<'a> {
        let mut full = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
        Slicer {
            full: full,
            cur_slice: full.as_mut_slice()
        }
    }
}

#[gat]
impl<'a> LendingIterator for Slicer<'a>
{
    type Item<'next>
    where
        Self: 'next,
    =
        &'next [u32]
    ;

    fn next(&mut self) -> Option<&[u32]> {
        if self.cur_slice.len() != 0 {
            // In the actual program, this is streaming new data into the
            // buffer. This is just a minimal example.
            self.cur_slice = self.cur_slice[..self.cur_slice.len() - 1].as_mut();
            Some(self.cur_slice)
        } else {
            None
        }
    }
}

fn main() {
    let mut slicer = Slicer::new();
    while let Some(x) = slicer.next() {
        println!("{x:?}");
    }
}

I'm still getting a few separate errors, the two mains one being error[E0515]: cannot return value referencing local variable `full` and error: lifetime may not live long enough:

error[E0515]: cannot return value referencing local variable `full`
  --> src\main.rs:11:9
   |
11 | /         Slicer {
12 | |             full: full,
13 | |             cur_slice: full.as_mut_slice()
   | |                        ---- `full` is borrowed here
14 | |         }
   | |_________^ returns a value referencing data owned by the current function
error: lifetime may not live long enough
  --> src\main.rs:31:30
   |
19 | impl<'a> LendingIterator for Slicer<'a>
   |      -- lifetime `'a` defined here
...
28 |     fn next(&mut self) -> Option<&[u32]> {
   |             - let's call the lifetime of this reference `'1`
...
31 |             self.cur_slice = self.cur_slice[..self.cur_slice.len() - 1].as_mut();
   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'a`

Am I barking up the wrong tree with lending iterators, or is there a way to accomplish this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants