Implement Traits on External Types in Rust

shakyapeiris

Shakya Peiris

Posted on April 2, 2024

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.

💖 💪 🙅 🚩
shakyapeiris
Shakya Peiris

Posted on April 2, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related