Open jorgecarleitao opened 1 year ago
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)
}
}
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?
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
how would
look like if say we want to return chunks of size 8 of the
Vec<u8>
Thanks for the cool crate!