In another article we saw how to implement a trait to reverse a string. It turns out the implementation was not perfect and the unicode_reverse crate would do a better job at the task, but for showing how to add a trait this is a nice example.
In this article we'll see two crates. One implements the trait, the other uses it.
Crate implementing a trait
- We added the
pub
keyword in-front of the wordtrait
. - We also removed the
main
function as that will be in the crate that uses this one. - We also renamed the file from
src/main.rs
tosrc/lib.rs
. - Lastly we added some tests. This is not required, but it is a good practice to have tests. (I should have added some tests to the previous article as well, but I was lazy.)
examples/reverse-trait-for-strings-public/src/lib.rs
pub trait Reverse {
fn reverse(&self) -> String;
}
impl Reverse for str {
fn reverse(&self) -> String {
self.chars().rev().collect::<String>()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let text = "Hello";
assert_eq!("olleH", text.reverse());
let text = "mañana";
assert_eq!("anañam", text.reverse());
}
}
Add the crate as a dependency
Because the above crate is local only, Cargo.toml
needs to point to the folder where it is located. (and the full name of the above crate is reverse-trait-for-strings-public
.
examples/reverse-trait-for-strings-use-public/Cargo.toml
[package]
name = "reverse-trait-for-strings-use-public"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
reverse-trait-for-strings-public = { version = "0.1.0", path = "../reverse-trait-for-strings-public" }
Using the trait from the other crate
This is basically the same code we had in the previous article when we had the trait implementation in the same file. The only difference is that we have the first line importing the trait:
use reverse_trait_for_strings_public::Reverse;
examples/reverse-trait-for-strings-use-public/src/main.rs
use reverse_trait_for_strings_public::Reverse;
fn main() {
let text = "Welcome to Rust!";
let reversed = text.reverse();
println!("{}", reversed);
let twice = reversed.reverse();
println!("{}", twice);
assert_eq!(twice, text);
}
Conclusion
It is quite easy to create a reusable crate even if we only want to reuse it locally in other crates without publishing it to the whole world.