How to use more than one Trait implementation while avoiding conflicts
Tags: rust, showdev
Published: 2019-05-21 04:42:48

# Problem
Say you initially have code like this:
```rust
struct DeserializeError(String);
trait Deserialize<T> {
    fn into_type(self) -> Result<T, DeserializeError>
}

struct Foo {}
impl Deserialize<Foo> for Vec<u8> {
    fn into_type(self) -> Result<Foo, DeserializeError> {
        unimplemented!() // Vec<u8> -> Foo
    }
}

struct Bar {}
impl Deserialize<Bar> for Vec<u8> {
    fn into_type(self) -> Result<Bar, DeserializeError> {
        unimplemented!() // Vec<u8> -> Bar
    }
}
```
and later down the road, you need to write a generic implementation of `Deserialize` that requires the use of `Deserialize<Foo>`, `Deserialize<Bar>`, and whatever other implementations exist in your code base.

The problem I encountered was when I initially tried to do the following:
```rust
struct Wrapper<T> { foo: Foo, t: T }

// first 4 bytes are Foo, the rest will make up T
impl<T> Deserialize<Wrapper<T>> for Vec<u8> {
    fn into_type(self) -> Result<Wrapper<T>, DeserializeError> {
        self[0..=3].to_vec().into_type().and_then(|foo: Foo| {
            self[4..].to_vec().into_type().map(|some_t: T| {
                Wrapper { foo, t: some_t }
            })
        })
    }
}
```
Unfortunately, you'll get the following error:
```
|     self[4..].to_vec().into_type().map(|some_t: T| {
|                                    ^^^^^^^^^^^^^^^^^^ the trait `Deserialize<T>` 
|     is not implemented for `std::vec::Vec<u8>`
 ```
The compiler wonderfully suggested the following advice though:
```
consider adding a `where std::vec::Vec<u8>: Deserialize<T>` bound
```
Ok, so let's try that:
```rust
impl<T> Deserialize<Wrapper<T>> for Vec<u8>
    where Vec<u8>: Deserialize<T> {
    fn into_type(self) -> Result<Wrapper<T>, DeserializeError> {
        self[0..=3].to_vec().into_type().and_then(|foo: Foo| {
            self[4..].to_vec().into_type().map(|some_t: T| {
                Wrapper { foo, t: some_t }
            })
        })
    }
}
```
But now we get the following compiler error:
```
   = note: expected type `Foo`
              found type `T`
```
Why? Because the `where` bound has stated that `Vec<u8>` in this scope must implement `Deserialize<T>`, and based on my best guess, has explicitly enforced only that implementation into scope as well. So my problem is that although I don't have conflicting _implementations_ of the trait for `Vec<u8>`, I had conflicting _use_ of the trait.

# Solution
This took me awhile to find, but the solution was in the second edition of "The Rust Programming Language" book. In the [Advanced Traits](https://doc.rust-lang.org/book/ch19-03-advanced-traits.html) section, the key was the subsection "_Fully Qualified Syntax for Disambiguation: Calling Methods with the Same Name_".

Although this section was regarding explicitly stating which method to use from multiple traits with the same name (conflicting method names, not trait names), it did the trick here.

```rust
impl<T> Deserialize<Response<T>> for Vec<u8>
    where Vec<u8>: Deserialize<T> {
    fn into_type(self) -> Result<Wrapper<T>, DeserializeError> {
        Deserialize::<Foo>::into_type(self[0..=3].to_vec()).and_then(|foo: Foo| {
            Deserialize::<T>::into_type(self[4..].to_vec()).map(|some_t: T| {
                Wrapper { foo, t: some_t }
            })
        })
    }
}
```
I still retain the `where` bound so that the implementation is in scope by the compiler, but by using the fully qualified syntax—including the generic type—I'm telling the compiler exactly which implementations I actually want to use. And of course, it compiles. From the perspective of a Scala developer, this is kind of like temporarily skipping implicit class conversion and manually calling the implementation you want.

_originally posted as a [gist](https://gist.github.com/kdrakon/ff44b55ea0baa012382b9590362d5fef)._