Если применение функции могло изменить вариант перечисления, то вообще нет смысла реализовывать ее на уровне варианта перечисления. Я бы просто реализовал его на уровне перечисления, например:
impl Number {
fn dec(&mut self) {
*self = match self {
Number::I(i) => Number::I(Integer(i.0-1)),
Number::N(n) if n.0==0 => Number::I(Integer(-1)),
Number::N(n) => Number::N(Natural(n.0-1))
}
}
}
Если вы действительно хотите, чтобы эта функция была доступна на уровне варианта, то, по крайней мере, в случае Natural::dec
, она не будет всегда быть успешным. Следовательно, функция должна возвращать что-то, чтобы указать случай, когда невозможно уменьшить его и по-прежнему оставаться натуральным числом.
impl Integer {
fn dec(&mut self) {
self.0 -= 1;
}
}
struct NotNatural ();
impl Natural {
fn dec(&mut self) -> Result<(), NotNatural> {
if self.0 == 0 {
Err(NotNatural())
} else {
self.0 -= 1;
Ok(())
}
}
}
impl Number {
fn dec(&mut self) {
match self {
Number::I(ref mut i) => i.dec(),
Number::N(ref mut n) => match n.dec() {
Ok(_) => (),
Err(_) => {
*self = Number::I(Integer(-1));
()
}
}
}
}
}
Площадка