#Implementing a trait for iterators of a specific type

10 messages · Page 1 of 1 (latest)

rose hedge
#

I have a struct

struct MyStruct {
  item: u32,
}

and a trait

trait MyTrait {
  fn my_fn(&self) {
    println!("Hello");
  }
}

and I'd like to implement MyTrait for iterators over owned and referenced MyStructs. I've tried something along the lines of:

impl<I: AsRef<MyStruct>, T: IntoIterator<Item = I>> MyTrait for T{}

but this results in no method named my_fn found for struct std::slice::Iter in the current scope. I've also tried with Item=MyStruct rather than the generic using AsRef, but then I can only implement the trait for iterators of either owned or borrowed MyStructs, but not both

Here's a playground link https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=72812bc9723a66820b55f387e8658283

potent oracle
#

Hey, I added a check function in to test the bounds of the iterator and get this message that MyStruct needs to implement AsRef<MyStruct> for the bounds to work

#

?play

struct MyStruct {
  item: u32,
}

trait MyTrait {
  fn my_fn(&self) {
    println!("Hello");
  }
}

impl<I: AsRef<MyStruct>, T: IntoIterator<Item = I>> MyTrait for T{}

fn check<T: IntoIterator>(t: T) where T::Item: AsRef<MyStruct> {}

fn main() {
    let temp = vec![MyStruct{item: 1}, MyStruct{item: 2}];
    check(temp.iter());
    //temp.iter().my_fn();
}
sick craterBOT
#
error[E0277]: the trait bound `MyStruct: AsRef<MyStruct>` is not satisfied
  --> src/main.rs:17:11
   |
17 |     check(temp.iter());
   |     ----- ^^^^^^^^^^^ the trait `AsRef<MyStruct>` is not implemented for `MyStruct`
   |     |
   |     required by a bound introduced by this call
   |
   = note: required for `&MyStruct` to implement `AsRef<MyStruct>`
note: required by a bound in `check`
  --> src/main.rs:13:48
   |
13 | fn check<T: IntoIterator>(t: T) where T::Item: AsRef<MyStruct> {}
   |                                                ^^^^^^^^^^^^^^^ required by this bound in `check`

For more information about this error, try `rustc --explain E0277`.```
potent oracle
#

Adding the implementation in sorts everything out

#

?play

struct MyStruct {
  item: u32,
}

impl AsRef<MyStruct> for MyStruct {
    fn as_ref(&self) -> &Self {
        self
    }
}

trait MyTrait {
  fn my_fn(&self) {
    println!("Hello");
  }
}

impl<I: AsRef<MyStruct>, T: IntoIterator<Item = I>> MyTrait for T{}

fn main() {
    let mut temp = vec![MyStruct{item: 1}, MyStruct{item: 2}];
    temp.iter().my_fn();
    temp.iter_mut().my_fn();
    temp.into_iter().my_fn();
}
sick craterBOT
#
Hello
Hello
Hello```
potent oracle
#

It looks like the Borrow trait has a blanket impl of Borrow<T> for all T so if you used that instead of AsRef then don't need to implement it yourself

#

?play

use std::borrow::Borrow;

struct MyStruct {
  item: u32,
}

trait MyTrait {
  fn my_fn(&self) {
    println!("Hello");
  }
}

impl<I: Borrow<MyStruct>, T: IntoIterator<Item = I>> MyTrait for T{}

fn main() {
    let mut temp = vec![MyStruct{item: 1}, MyStruct{item: 2}];
    temp.iter().my_fn();
    temp.iter_mut().my_fn();
    temp.into_iter().my_fn();
}
sick craterBOT
#
Hello
Hello
Hello```