Is there a way to extend third party traits in current stable Rust (without specialization)?
Background is that I was looking into extending Serde with things that won't be accepted in the core.
I've created a minimal example showing the problem (Playground link):
// This is about issued with extending third party traits.
// Imagine the next two traits are from a third party in a separate crate
trait ThirdPartyData {
fn data(&self) -> u8;
}
trait ThirdParty {
fn hello<D>(&self, data: D)
where
D: ThirdPartyData;
}
// My implementation for the `ThirdPartyData` trait
struct MyData {
value: u8,
}
impl ThirdPartyData for MyData {
fn data(&self) -> u8 {
self.value
}
}
// I define an extentsion trait to have additional functionality on the `data` item
trait ThirdPartyDataExt: ThirdPartyData {
fn more_info(&self) -> u8;
}
// This is an implementation of a third party trait where I would like to call a method from my
// extension trait
struct MyStruct {}
impl ThirdParty for MyStruct {
fn hello<D>(&self, data: D)
where
D: ThirdPartyDataExt,
// I've tried adding the extension trait as additional bound, but that doesn't work as
// it's an extra requirement the original trait doesn't have
//D: ThirdPartyData + ThirdParyDataExt,
{
println!("data: {:?}", data.data());
// The next line is the problem, as `data` doesn't have the correct trait bounds
println!("more_info: {:?}", data.more_info());
}
}
fn main() {
let my_data = MyData { value: 6 };
let my_struct = MyStruct {};
my_struct.hello(my_data);
}
You could add a blanket implementation for ThirdPartyData
, but then you couldn't implement ThirdPartyDataExt
for MyData
:
impl<T: ThirdPartyData> ThirdPartyDataExt for T {
fn more_info(&self) -> u8 {
1
}
}
I hope that I'm missing something and there's a solution (that might even be completely different to the way I tried it).