Reputation: 739
I work on an implementation of the Repository pattern in Rust.
I need to have two (or more) files:
entity.rs
— data descriptionsrepository.rs
— data access methodsProblem:
One file implies one mod. This means that for a function in repository.rs
to have access to struct field from entity.rs
it is required that field
be pub
. Is there some way to avoid this?
Upvotes: 1
Views: 158
Reputation: 299730
In Rust, modules are self-contained. Unlike C++ or Java there is no cheating via either friend
or the use of reflection.
As such, if you (arbitrarily) attempt to separate the definition of the struct
from the methods in charge of maintaining its encapsulation, you will fight against the language.
Solution 1: Prefer non-member non-friend functions
Define the methods absolutely requiring access to the fields in entity.rs
; if you follow the "Prefer non-member non-friend functions" guideline from C++, you should see that actually most methods do NOT need to access the fields directly. For example, empty
can be defined in terms of len
:
fn empty(c: &Container) -> bool { c.len() == 0 }
Then, repository.rs
can add many other methods if it needs to, but has to go through the "minimal" interface exported by entity.rs
to achieve its needs. Since you are in control of both modules, you can tweak the methods of entity.rs
at will anyway so it should not be an issue.
I would point out that encapsulation-wise, this is the sensible decision: reducing the number of methods that may access the internals of an object reduces the number of methods that may put this object in an invalid state.
This solution is advantageous because you are not fighting the language.
Solution 2: Total split
Another solution is to duplicate your entities:
This is achieved by:
pub struct SomeEntImpl {
pub field0: i32,
}
pub struct SomeEnt {
inner: SomeEntImpl,
}
The authorized modules will be given references to a SomeEntImpl
, while others will have to use the restricted interface available through SomeEnt
. The control over who sees what will be achieved by careful exports.
This solution will probably drive you insane.
Upvotes: 5