I have an enum with two variants and I have a function that might change the active variant of the enum. I would also like to split my code between the two enum variants, but this creates the challenge that the function of the variant type can't take an mutable reference to itself, since it cannot change the variant of an enum it's not a part of. If the function takes ownership, I have to use a dummy variable, which is fine for my actual application, but not in general.
struct Integer (i32);
struct Natural (u32);
enum Number {
I(Integer),
N(Natural),
}
impl Integer {
// Decrement
fn dec(&mut self) {
self.0 -= 1;
}
}
impl Natural {
// Zero is a natural number that when decremented is not a natural number
// therefore dec cannot take a &mut self
fn dec(self) -> Number {
if self.0 == 0 {
Number::I(Integer(-1))
} else {
Number::N(Natural(self.0 - 1))
}
}
}
impl Number {
// Is there a better way to do this?
fn dec(&mut self) {
let result = match self {
Number::I(int) => {
int.dec();
return
}
Number::N(nat) => {
// For this example making a dummy is possible
// but what if it's not?
let dummy = Natural(0);
let extracted = std::mem::replace(nat, dummy);
extracted.dec()
}
};
*self = result;
}
}
// Something like this would be nice
fn transform<T, F>(val: &mut T, f: F) where F : FnOnce(T) -> T {
todo!("Magic!");
}
All of this feels a bit tedious, so I have a suspicion that I've missed some simpler way of doing this.