Reputation: 1530
I want to implement a simple utility/helper function in Rust. The function just concatenates the path in a struct (from an external crate) and the argument passed. Is it more idiomatic to implement the helper-function as a normal function or as function of a custom trait?
The implementation of the trait-based approach:
use std::path::{Path, PathBuf};
pub trait RepositoryExt {
fn get_full_path(&self, path_in_repository: &Path) -> PathBuf;
}
impl RepositoryExt for othercrate::Repository {
// othercrate::Repository's workdir() returns its path
fn get_full_path(&self, path_in_repository: &Path) -> PathBuf {
self.workdir().join(path_in_repository)
}
}
With just a function:
pub fn get_repository_full_path(repo: othercrate::Repository,
path_in_repository: &Path) -> PathBuf {
repo.workdir().join(path_in_repository)
}
The trait-based approach shortens the code when using the helper-function, but I'm worried that it may introduce difficulty to understand where it's defined.
Though both implementations should work, I want to know which is the recommended way in Rust.
Upvotes: 3
Views: 2047
Reputation: 88656
(Disclaimer: I am not entirely sure about this. If this answer receives enough™ upvotes, I will delete this disclaimer)
Good question! I have already seen both solution in the wild and would say that both are valid to use. Or in other words: neither of the two solutions are considered bad.
However, I'd say that using the Ext
-trait approach is often a slightly better choice due to these advantages:
f(f(a, f(d, e)), c)
.Trait::func(self_object, arg)
.But of course there are some disadvantages (you already mentioned one):
use
the trait).Upvotes: 4