Preface
The Id type is a critical structure of the rspotify model, and we have contributed a lot to improve its usability and ergonomics.
The problem
The key problem we encounter when using different Id type is that some endpoints accept PlayableId and PlayContextId as parameter, and the uri(we need to send to Spotify API) of these Id depending on the type of Id:
/// Examples: `spotify:album:6IcGNaXFRf5Y1jc7QsE9O2`,
/// `spotify:track:4y4VO05kYgUTo2bzbox1an`.
fn uri(&self) -> String {
format!("spotify:{}:{}", self._type(), self.id())
}
So we need dynamic dispatch mechanism, our previous implementation was built on Box and dyn, with the cost of overhead and usability.
Our solution
Now, the current implementation regains the ability of dynamic dispatch by leveraging the power of enum_dispatch. As @eladyn suggested, we use Cow<'a, str> to hold the data of Id, instead of maintaining two versions of Id data, the borrowed version and owned version.
Trait Hierarchy

Reference
Credit to @marioortizmanero and @eladyn