How can we create generic method with specialized implementations?

Viewed 98

I have specialised implementation for concrete type(f64):

struct Total {
    total: f64
}

impl AddAssign<f64> for Total {
    fn add_assign(&mut self, rhs: f64) {
        self.total += rhs;
    }
}

trait TakeForTotal {
    fn get(&self) -> f64;
}

impl<T: TakeForTotal> AddAssign<&T> for Total {
    fn add_assign(&mut self, taker: &T) {
        self.add_assign(taker.get());
    }
}

This is simplified code, for demonstrate my problem. In real:

  • Total is a Minimum and Maximum.
  • TakeForTotal is a trait for containers, in real is traits High and Low, and exist structs that implements these traits.
  • This implementation is needed for work with f64 and with containers.
  • Manually fetching numeric values from containers is possible, but it's easy to make a mistake:
minimum.add(container)
maximum.add(container)
// is better than:
minimum.add(container.low)
maximum.add(container.high)

It's easy to confuse high with low, and is critical bug.


Now I want to make Total for all types that implement AddAssign, but I can't do that, becouse for

struct Total<T> {
    total: T
}

implementations:

impl<T: AddAssign> AddAssign<T> for Total<T> 

and

impl<T: TakeForTotal> AddAssign<&T> for Total<T::Output> where T::Output: AddAssign

now is conflicting. How best to implement? Or is it impossible?

Full code:

struct Total<T> {
    total: T
}

impl<T: AddAssign> AddAssign<T> for Total<T> {
    fn add_assign(&mut self, rhs: T) {
        self.total += rhs;
    }
}

trait TakeForTotal {
    type Output;

    fn get(&self) -> Self::Output;
}

impl<T: TakeForTotal> AddAssign<&T> for Total<T::Output> where T::Output: AddAssign {
    fn add_assign(&mut self, taker: &T) {
        self.add_assign(taker.get());
    }
}
0 Answers
Related