How to define methods for a type embedded in a struct that either implemented trait A or B?

I have two traits and a struct:

pub trait A {}

pub trait B {}

struct S<T> { a: T }

I can define a method for S<T> only when T implements trait A and B:

impl<T: A + B> S<T> {
    pub fn do_something(&self) {
        println!("do_something");
    }
}

How can I define methods for S<T> when T implements trait A or B? I tried to write two impl but it doesn't work:

impl<T: A> S<T> {
    pub fn do_something_else(&self) {
        println!("do_something_else");
    }
}

impl<T: B> S<T> {
    pub fn do_something_else(&self) {
        println!("do_something_else");
    }
}

I got this error:

error[E0592]: duplicate definitions with name `do_something_else`
  --> src\main.rs:14:5
   |
14 |     pub fn do_something_else(&self) {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `do_something_else`
...
20 |     pub fn do_something_else(&self) {
   |     ------------------------------- other definition for `do_something_else`

What will happen when I try calling S::do_something_else if T implements both A and B?

1 Like

I think you should call through S<A> or S<B>, like S<A>::do_something_else()

I don't think you can define two methods with same name on a struct, but you can implement traits with same named methods on a struct and then call the method via trait::method(struct).

Also, if you are willing to call the method like S<A>::do_something_else(struct), then you would be already knowing the generic parameter of struct (A, for examle), and you can just change the name of methods. Like this:

impl<T: A> S<T> {
    pub fn do_something_else_for_a(&self) {
        println!("do_something_else");
    }
}

impl<T: B> S<T> {
    pub fn do_something_else_for_b(&self) {
        println!("do_something_else");
    }
}

and then use them like below:

S<A>::do_something_else_for_a(s);
S<B>::do_something_else_for_b(s);
1 Like