Enum assignment

I would like to have an enum that represent different states, and transition between these using functions.

The problem is that I am not able to construct a new state (enum variant) that has some struct members, and I don't know why this does not work.


struct Foo {
    state: FooState,
}

// the different states
enum FooState {
    FooNewState,
    FooInitState,
}

// state 1
struct FooNewState;

// state 2
struct FooInitState {
    x: u16,
}

impl Foo  {
    const fn new() -> Self {
        Self { state: FooState::FooNewState }
    }

    fn init(&mut self, x: u16) {
        match self.state {
            FooState::FooNewState => {
                self.state = FooState::FooInitState{ x }   // <== does not work
            },
            _ => panic!("")
        };
    }
}

static FOO: Foo = Foo::new();

The error message I get is:

error[E0559]: variant `FooState::FooInitState` has no field named `x`
  --> src/main.rs:89:58
   |
89 |                 self.state = FooState::FooInitState{ x }
   |                                                          ^ `FooState::FooInitState` does not have this field
   |
   = note: all struct fields are already assigned

You have to declare your fields in the enum variants. Your enum is a completely different type and has no connection to the structs that have the same name as its variants. This section of the book discusses enums in more detail.

struct Foo {
    state: FooState,
}

// the different states
enum FooState {
    FooNewState,
    FooInitState { x: u16 },
}

impl Foo  {
    const fn new() -> Self {
        Self { state: FooState::FooNewState }
    }

    fn init(&mut self, x: u16) {
        match self.state {
            FooState::FooNewState => {
                self.state = FooState::FooInitState{ x }   // <== does not work
            },
            _ => panic!("")
        };
    }
}

Playground.

1 Like