Multiple Trait implementations based on generic type bound


#1

Hey guys,
I’m writing a small graph library to practice stuff from my computer science studies.
I have a generic data type Graph and want to implement fmt::Display on it.
Now I want to have 2 different implementations, based on whether T implements Display or not:
https://play.rust-lang.org/?gist=8aa367a10ad6f3a39d8fa56fb3c54eb9&version=stable
Is there any way to achieve this?

Thanks in advance,
Anton


#2

This is not currently possible, but will be enabled by specialization


#3

I’m not certain if specialization will definitely enable this for Display because, last time I checked, specialization requires opt-in - it’s unclear whether traits and blanket impls will do that. But the technique itself should make cases like this possible.

A couple of workarounds that spring to mind:

  1. Require T: Display for Graph<T>'s Display impl. Anything that isn’t Display can always be wrapped with some dummy type that implements Display but doesn’t do anything (or prints some placeholder text).
  2. Make Graph<T, F> where F is a formatting function that caller providers. They know their type, and can either delegate to its Display (if it has one) or provide some other output for non-Display. You can also skip the F generic parameter and instead store it as a boxed closure inside Graph<T> but require it during construction.

#4

Looks like I’ll have to stick to the first case for now, don’t need Display that much anyways, I was just curious about what’s possible :slight_smile: Anyways, thank you guys a lot (and I definitely will look at this specialization thing anyways, looks interesting)

Have a nice day everyone
Anton