I am building a custom data structure which supposes to return an iterator for its elements. If simplified, it can look like this:
use std::iter::{Iterator, StepBy};
// My collection which returns iterator to it's elements
pub trait MyCollection<'a, T: 'a> {
type I: Iterator<Item = &'a T>;
fn find_something(&'a self) -> Self::I;
}
Now, in some cases, I would like to create a "wrapper" for this collection that transforms the elements returned by the iterator. For the sake of this example let's assume that this wrapper allows skipping over some elements of the original iterator:
// Wrapper for a collection that allows iterating over elements with a step
pub struct StepWrapper<'a, A>(&'a A, usize);
impl<'a, T: 'a, A: MyCollection<'a, T>> MyCollection<'a, T> for StepWrapper<'a, A> {
type I = StepBy<A::I>;
fn find_something(&'a self) -> Self::I {
self.0.find_something().step_by(self.1)
}
}
// Function which takes a collection and a step value and returns a wrapped collection
fn wrap<'a, T: 'a, A: MyCollection<'a, T>>(a: &'a A, step: usize) -> impl MyCollection<'a, T> {
StepWrapper(a, step)
}
Unfortunately, I get a compilation error when trying to use this code:
// Example
impl<'a> MyCollection<'a, u64> for Vec<u64> {
type I = std::slice::Iter<'a, u64>;
fn find_something(&'a self) -> Self::I {
return self.iter();
}
}
fn main() {
let collection = vec![12, 13, 14];
let wrapped = wrap(&collection, 2);
// Error now
let result = wrapped.find_something().skip(1).next();
// ^^^^^^^ borrowed value does not live long enough
println!("{}", result.unwrap());
}
I understand that StepWrapper<'a, A>::find_something requires self to be borrowed for the same lifetime as the original collection. But all my attempts to decouple lifetimes of a collection and a wrapper were unuseful. Essentially a find_something function in the wrapper needs to return a result which outlives itself. Is there a way to express it in Rust?
'afrom theselfI get an error inimpl<'a> MyCollection<'a, u64> for Vec<u64>. - Peter Popov