How to implement custom method to a library?

Peace be upon you,

Its easy to describe actual problem with code, lets say I am using a library called animals

use animals::Duck;

let mut duck = Duck::new();
duck.walk();
duck.swim();
duck.fly();
// custom method
duck.talk(); 

Of course, duck can't talk, But how to implement our own method for Duck ?

impl Duck {
    fn talk(&self) { ... }
}

I got this error:

error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined
  |
  | / impl Duck {
  | |     fn talk(&self) { ... }
  | | }
  | |_^ impl for type defined outside of crate.
  |
  = note: define and implement a trait or new type instead

https://rust-lang.github.io/rfcs/0445-extension-trait-conventions.html

Note that methods aren’t much different to functions in rust, so the simplest approach might be to define a function

fn talk(this: &Duck) { … }

If you want to have method-call syntax, the easiest approach is with an “extention trait”. In the context of your example, this would look like

trait DuckExt {
    fn talk(&self);
}
impl DuckExt for Duck {
    fn talk(&self) { … }
}

note that the method call syntax with such a trait is only available if the trait is in scope, so from a different module you’d need to include a use your::path::to::DuckExt; item.

2 Likes

You removed the question, but the example would be

mod imagine_this_being_an_external_crate {
    pub struct Duck;
}

use imagine_this_being_an_external_crate::Duck;

trait DuckExt {
    fn talk(&self);
}

impl DuckExt for Duck {
    fn talk(&self) {}
}

fn give_me_duck() -> Duck {
    Duck
}

mod different_module {
    fn foo()  {
        let duck = super::give_me_duck();
        // duck.talk(); does not work
        super::DuckExt::talk(&duck); // only fully qualified, i.e. non-method-syntax works
    }
    fn bar()  {
        use super::DuckExt;
        let duck = super::give_me_duck();
        duck.talk(); // works!
    }
}
1 Like

Sorry, I understanded , I understand ... But thanks again for your quick replay, also for you answer...