DEV Community

Cover image for Implement Traits on External Types in Rust
Shakya Peiris
Shakya Peiris

Posted on

Implement Traits on External Types in Rust

Say you are using an type from an external crate and you want to implement a specific functionality/method on that type. As an example say you are using the linked list of my recently developed rust_dsa crate and you want to implement a method on it to print it's values in the following format.
Linked list

let mut h = Node::new(Some(0));
// Snippet
println!("Linked list: {}", head);
Enter fullscreen mode Exit fullscreen mode

If it's from a local trait, you can simply implement the Display trait on it as follows

impl<T: Debug + Clone + Copy> fmt::Display for Node<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match &self.next {
            Some(next) => {
                print!(
                    "{} <- ",
                    Node {
                        value: self.value,
                        next: Some(next.cl)
                    }
                );
                write!(f, "{:?}", self.value.as_ref().unwrap())
            }
            None => {
                write!(f, "{:?}", self.value.as_ref().unwrap())
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

But since you are using Node which is from an external trait you will face the following error when you compile your binary

Error msg

So what can you do about it? You can simply implement a wrapper for that specific type and implement the Trait of your choice as follows by accessing the Type you want as a child of the Wrapper as a tuple element.

struct  Wrapper<'a, T>(&'a Box<Node::<T>>);
Enter fullscreen mode Exit fullscreen mode
impl<'a, T: Debug> fmt::Display for Wrapper<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match &self.0.next {
            Some(next) => {
                print!("{} <- ", Wrapper(&next));
                write!(f, "{:?}", self.0.value.as_ref().unwrap())
            },
            None => {
                write!(f, "{:?}", self.0.value.as_ref().unwrap())
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

That's it for new types and feel free to explore more on new types in Rust book's guide on Advanced traits.

Top comments (0)