Hi folks,
Could you please tell me if the following is possible?
(the commented code doesn't work)
Thank you
#[derive(Debug, PartialEq)]
pub struct Content {
number: i32,
}
#[derive(Debug, PartialEq)]
pub struct Thing {
content: Content,
}
#[derive(Debug, PartialEq)]
pub struct ManyThings {
things: Vec<Thing>,
}
pub struct ManyThingsIterator {
things_reversed: Vec<Thing>,
}
pub struct ManyThingsIteratorSlice<'a> {
things: &'a [Thing],
}
impl Iterator for ManyThingsIterator {
type Item = Thing;
fn next(&mut self) -> Option<Self::Item> {
self.things_reversed.pop()
}
}
impl<'a> Iterator for ManyThingsIteratorSlice<'a> {
type Item = &'a Thing;
fn next(&mut self) -> Option<Self::Item> {
if let Some((out, rest)) = self.things.split_first() {
self.things = rest;
Some(out)
} else {
None
}
}
}
impl IntoIterator for ManyThings {
type Item = Thing;
type IntoIter = ManyThingsIterator;
fn into_iter(self) -> Self::IntoIter {
let mut things_reversed = self.things;
things_reversed.reverse();
ManyThingsIterator { things_reversed }
}
}
impl<'a> IntoIterator for &'a ManyThings {
type Item = &'a Thing;
type IntoIter = ManyThingsIteratorSlice<'a>;
fn into_iter(self) -> Self::IntoIter {
ManyThingsIteratorSlice {
things: self.things.as_slice(),
}
}
}
pub trait GetContent {
fn move_it_out(self) -> Content;
fn get_it(&self) -> &Content;
}
pub trait GetContentMultiple {
fn move_it_out_multiple<T>(self) -> Vec<Content>
where
Self: Sized + IntoIterator<Item = T>,
T: GetContent,
{
self.into_iter().map(|inp| inp.move_it_out()).collect()
}
fn get_it_multiple<'a, T>(self) -> Vec<&'a Content>
where
Self: Sized + IntoIterator<Item = &'a T>,
T: GetContent + 'a,
{
self.into_iter().map(|inp| inp.get_it()).collect()
}
}
impl GetContent for Thing {
fn move_it_out(self) -> Content {
self.content
}
fn get_it(&self) -> &Content {
&self.content
}
}
impl GetContentMultiple for ManyThings {}
#[test]
fn test_move_it_out_multiple() {
let a = ManyThings {
things: vec![
Thing {
content: Content { number: 0 },
},
Thing {
content: Content { number: 1 },
},
Thing {
content: Content { number: 2 },
},
],
};
assert_eq!(
a.move_it_out_multiple(),
vec![Content { number: 0 }, Content { number: 1 }, Content { number: 2 }]
)
}
#[test]
fn test_get_it_multiple() {
let a = ManyThings {
things: vec![
Thing {
content: Content { number: 0 },
},
Thing {
content: Content { number: 1 },
},
Thing {
content: Content { number: 2 },
},
],
};
let b = &a;
// assert_eq!(
// b.get_it_multiple(),
// vec![&Content { number: 0 }, &Content { number: 1 }, &Content { number: 2 }]
// )
}