I wish to write a generic function in Rust that can iterate repeatedly over a collection of elements, which in turn contain a collection that is repeatedly iterated over. The elements are pairs of (Label, Collection<Elem>)
, where Label
is some arbitrary type and Collection
is something that can be iterated over multiple times having elements of type Elem
. I specifically wish to perform repeated iterations without cloning any of the collections, accidentally or otherwise.
Examples of such collections:
let collection1 = vec![(1u8,vec![0u8,1u8]), (2u8,vec![2u8,3u8,4u8])];
let collection2 = LinkedList::from([("a",[1,2,3]),("b",[4,5,6])]);
An example of a non-generic function that can iterate over collection1
without cloning:
fn nesting(collection : &Vec<(u8,Vec<u8>)>) -> () {
for (l,c) in collection {
print!("{}: ",l);
for e in c.iter() {
print!("{}, ",e);
}
for e in c.iter() {
print!("{}, ",e);
}
println!();
}
for (l,_) in collection {
println!("{:?}",l);
}
}
One approach I've considered is like this:
fn nesting<'a, L:'a,N:'a,I:Clone+IntoIterator<Item=&'a (L,N)>>(collection: I) -> ()
{
for i in collection.clone() { /* ... */ };
for i in collection.clone() { /* ... */ };
}
While this can be called on a shared reference to a collection, it can also be called on a collection containing references, in which case the entire collection will be cloned. And what type constraint should N
have?
struct Elem;
fn take_elem(_: &Elem) {}
fn nesting<'a, Label, Outer, Inner>(collection: &'a Outer)
where
Inner: 'a,
Label: 'a,
&'a Outer: IntoIterator<Item = &'a (Label, Inner)>,
&'a Inner: IntoIterator<Item = &'a Elem>,
{
for (_label, inner) in collection {
for elem in inner {
take_elem(elem);
}
}
for (_label, inner) in collection {
for elem in inner {
take_elem(elem);
}
}
}
This is not the fullest generality possible (for example, it disallows collection that yield owned items with references), but I believe it should suffice for you.