I have an implementation for a public trait that repeats some work over multiple functions, so I'd like to DRY it up with a function that does the shared work, to be called from the functions actually meant to be used. So I have:
fn do_private_thing()
fn do_pub_1()
fn do_pub_2()
I don't want do_private_thing()
to be exposed in docs or used directly, because it doesn't do anything useful from the perspective of a user of the trait/implementation. But functions in public traits are not private.
I could make do_private_thing
a private function in the module where the trait implementation is located, but the trait does require that that function's work be done by any implementation of the trait. So I feel like I'm lying a little bit if I leave that code out of the implementation.
What's the reasonable way to lay this out in Rust?
Traits can have properties and methods with private and protected visibility too. You can access them like they belong to class itself. There is no difference. Traits can have a constructor and destructor but they are not for the trait itself, they are for the class which uses the trait.
The impl keyword is primarily used to define implementations on types. Inherent implementations are standalone, while trait implementations are used to implement traits for types, or other traits. Functions and consts can both be defined in an implementation.
I could make
do_private_thing
a private function in the module where the trait implementation is located
This is what I would do.
but the trait does require that that function's work be done by any implementation of the trait. So I feel like I'm lying a little bit if I leave that code out of the implementation.
This starts to be a bit less clear. When you say any implementation of the trait, then I no longer understand why you'd want to make it private. If another implementer of the trait needs this code, then it should be public in some fashion.
In many ways, this feels very similar to the question "how do I test private methods". My normal answer there is: don't. Instead, extract the code you want to test to a new public item and then test the item in isolation. The usual problem is that people don't want to expose the functionality on a specific piece of state, not that they don't want to expose the functionality at all.
In this case, create a new type that incorporates the shared logic and can then be exposed and used by whoever needs it. Alternatively, create a type that can be parameterized by a type implementing your trait and provides whatever extra functionality you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With