Say I have
struct Data;
enum State {
First(Data),
Second(Data, Data),
}
And I want to add a method to it converting First
to Second
:
impl State {
fn convert(&mut self, extra_data: Data) {
...
}
}
If Data
is not constructable in impl State
scope, this is impossible in safe Rust (right?).
And I can see two options:
- Add a placeholder variant to
State
:
enum State {
Empty,
First(Data),
Second(Data, Data)
}
impl State {
fn convert(&mut self, extra_data: Data) {
let mut this = State::Empty;
std::mem::swap(&mut this, self);
if let State::First(data) = this {
*self = State::Second(data, extra_data);
} else {
std::mem::swap(&mut this, self);
}
}
But this leaks implementation detail and implementation is unnecessarily long and error-prone.
- Change method signature to consuming
self
:
impl State {
fn convert(self, extra_data: Data) -> Self {
if let State::First(data) = self {
State::Second(data, extra_data)
} else {
self
}
}
}
But this is contagious in the sense that if a outer struct
holds State
and wants to call convert
in its own method, that method must comsume self
too.
I'm wondering if there's a better way to implement this pattern? Thanks!