I have an iterator from an external library over a type, in this case the iterator is EdgeIter<'a>
and the Item type is EdgeRef<'a>
. Now I want to implement my own iterator over my own items, containing an EdgeRef<'a>
, but provide additional methods. So I want to have the iterator GraphEdges<'a>
over Items of type GraphEdge<'a>
:
pub struct GraphEdge<'a> {
edge: EdgeRef<'a>,
}
impl<'a> GraphEdge<'a> {
pub fn contains_weight(&self, w: &usize) -> bool {
// ...
}
pub fn max_weight(&self) -> Option<&'a usize> {
// ...
}
}
And also the iterator GraphEdges<'a>
provides additional methods:
pub struct GraphEdges<'a> {
iter: EdgeIter<'a>,
}
impl<'a> std::iter::Iterator for GraphEdges<'a> {
type Item = GraphEdge<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.map(GraphEdge::from).next()
}
}
impl<'a> From<EdgeIter<'a>> for GraphEdges<'a> {
fn from(iter: EdgeIter<'a>) -> Self {
Self {
iter
}
}
}
impl<'a> GraphEdges<'a> {
pub fn max_edge(&self) -> Option<<Self as Iterator>::Item> {
// ...
}
pub fn max_weight(&self) -> Option<usize> {
// ...
}
pub fn group_by_weight(&self) -> Vec<Vec<GraphEdge<'a>>> {
// ...
}
pub fn sort_by_weight(&mut self) -> Vec<usize> {
// ...
}
// how can I do this?
pub fn filter_by_weight(self, w: &usize) -> Self {
self.filter(|e| e.contains_weight(w))
}
}
Here, the result of self.filter(|e| e.contains_weight(w))
is of type Filter<GraphEdges<'a>, [closure@...]>
, but I would like the type to remain GraphEdges<'a>
, and would like to only change the behaviour of the iterator, i.e. the contained items, not their type.
How is this supposed to be done?
Should I make GraphEdges
an enum, which can represent Filter
s, Map
s and EdgeIter
s internally?
Should I implement a GraphIterator
trait which contains all of my methods and implement it for all Iterators
over GraphEdge
s and use impl Trait
s as returns... that actually sounds like it would work..
Just leaving this here for documentation and maybe someone has an even better idea.