How can I disable struct construction but maintaining pattern matching in Rust?
Let's see an example:
struct OrderedPair(pub u32, pub u32);
impl OrderedPair {
fn new(a: u32, b: u32) -> Self {
if a < b {
Self(a, b)
} else {
Self(b, a)
}
}
}
It's obvious that I want to inhibit the construction of such struct (e.g. OrderedPair(2, 1)) and to use only the new method, in order to preserve the invariant. I know of 3 ways to do this:
- Make private the fields
struct OrderedPair(u32, u32);
- Add a private dummy field
struct OrderedPair(pub u32, pub u32, ());
- Make the struct non-exhaustive
#[non_exhaustive]
struct OrderedPair(pub u32, pub u32);
The issues are that with 1 I cannot access the members at all and with all three I cannot use pattern matching
let OrderedPair(min, max) = my_ordered_pair;
So is there a way to block struct construction but allow pattern matching?
I know that if we declare a mutable variable of that type with public access to members then the invariant can be broken by manually changing the members, but for now avoiding the struct constructor is enough.