Generic Definition of Iterator of Struct

I want to create a function that takes as a parameter an Iterator over a struct. Here's an example (playground here: Rust Playground):

struct foo {
    bar: u64
}

fn want_foo_iter<I>(foo_iter: I)
    where I: Iterator,
          I::Item: foo
{ }

The compiler complains because foo isn't a trait... so how do I specify that I want an Iterator of struct foo?

play

Ah, so you can specify the Item as a struct when used like Iterator<Item=foo>, but not the way I had it. Got it, but not overly sure why... what is the difference in syntax? Thanks!

I::Item: <...> is a bound for the Item type itself - you want a bound on I however.

One more (hopefully) hang-up with Iteartors and references: (playground here: Rust Playground)

fn want_iter(it: &mut Iterator<Item=Bar>) { }

fn main() {
    let map = BTreeMap::new();
    
    want_iter(&mut map.values());
}

Results in this error. I don't understand where &Bar is coming from as my Item for the Iterator for want_iter is clearly just Bar, and even Values<'_, &str, Bar> doesn't a have a reference to Bar:

error[E0271]: type mismatch resolving `<std::collections::btree_map::Values<'_, &str, Bar> as std::iter::Iterator>::Item == Bar`
  --> src/main.rs:16:15
   |
16 |     want_iter(&mut map.values());
   |               ^^^^^^^^^^^^^^^^^ expected reference, found struct `Bar`
   |
   = note: expected type `&Bar`
              found type `Bar`
   = note: required for the cast to the object type `std::iter::Iterator<Item=Bar>`

Values implements Iterator<Item=&V> so it yields references but your signature asked for an iterator that yields values. So you’d want:

fn want_iter<'a>(it: &mut Iterator<Item=&'a Bar>) { }

Any reason you’re using a trait object for the iterator? Typically you can abstract over whether an iterator internally contains refs or values using generics. But not sure if you need/want trait objects on purpose here.

I don't need a trait object... I'm just looking for something that I can call .next() on and get a Bar that I'm then going to serialize and write to disk.

How would I abstract over if Item is a reference or not, while still requiring it be a struct of type Bar?

Here is how I’d write it. Let me know if you have questions.

Ah, I did not know about Borrow, thanks!