How to extend functionality of 3rd party type?
I'm using cursive for my project and there is a Dialog struct. In C++ I'd inherit from it and simply add the desired functionality. How to do it in rust?
Thanks
How to extend functionality of 3rd party type?
I'm using cursive for my project and there is a Dialog struct. In C++ I'd inherit from it and simply add the desired functionality. How to do it in rust?
Thanks
There are a few approaches:
if you want to implement a third-party trait B
for Dialog
, you can create a newtype
struct MyDialog(Dialog);
and then impl B for MyDialog
if you want to package additional data with Dialog
, you'd create a new struct like this:
struct DialogPlus {
dialog: Dialog,
extras: MyData,
}
if you just want to write your own functions that take a Dialog
as receiver, so that you can call them with method syntax, you can write an extension trait:
trait DialogExt {
fn my_extra_method(&self) -> Foo;
}
impl DialogExt for Dialog {
fn my_extra_method(&self) -> Foo {
/* implementation goes here */
}
}
Thanks, will check that out and let you know how it went.
Hi, unfortunately none of those solutions work as I need to extend existing Dialog's trait. So the situation is:
Dialog has a trait View and I need to modify one method of this trait to suit MyDialog.
Is this achievable?
Could you not create a new MyDialog
type and implement View
on MyDialog
? I.e. what's wrong with the two first solutions?
Would that mean that I have to implement all of the required methods from that trait? Because I only need to modify one and leave the rest as they are.
Yes, you need to implement those too, but you can forward the call to the inner dialog.
For any methods you don't want to override, you can implement them by forwarding to the inner class. Currently, you have to do this manually, which is simple but involves a lot of boilerplate for traits with many required methods:
struct MyDialog {
inner: Dialog,
}
impl View for MyDialog {
// This method is overridden.
fn do_stuff(&self) {
// new code goes here
}
// These methods all delegate to `self.inner`.
fn foo(&self) { self.inner.foo() }
fn bar(&self, count: usize) { self.inner.bar(count) }
fn baz(&self, s: &str) { self.inner.baz(s) }
}
If you are doing this frequently for the same trait, writing a macro can help eliminate the boilerplate. There are proposals for dedicated syntax to simplify such code.