How to implement TypeState instead of enums for

Hey all,
How can you implement the typestate pattern with generic types instead of an enum for a linked list?
Would this have any performance impact?

Here is some minimal example:

    enum EnumVariant {
        A,
        B,
    }
    impl EnumVariant {
        /// abstract example for the function that changes the Enum Variant
        pub fn change(&mut self) {
            if let EnumVariant::A = self {
                *self = EnumVariant::B
            }
        }
        /// abstract example for functions that depend on the Enum
        pub fn do_something(&self) {
            match self {
                Self::A => println!("a"),
                Self::B => println!("b"),
            }
        }
        pub fn do_something_for_a(&self) {
            if let Self::A = self {
                println!("a only")
            }
        }
    }

    /// master struct that owns many of these enums
    struct MasterStructEnumVariant {
        vec: Vec<EnumVariant>,
    }
    impl MasterStructEnumVariant {
        pub fn change(&mut self) {
            self.vec.iter_mut().for_each(|e| e.change());
        }
    }

For the real example the do_something* functions all boilerplate code.. The MasterStructEnumVariant contains a vector of these enums and in the real example, EnumVariant::B will again contain a vector to other MasterStructEnumVariant.

How would it be possible to change this to a typestate pattern?
this would directly eliminate the boilerplate code for those individual functions...

    struct StructA;
    struct StructB;
    struct TypeStateVariant<T> {
        val: T,
    }
    impl TypeStateVariant<StructA> {
        pub fn change(&mut self) {
            // how to correctly specify the types?
            *self = StructB;
        }
    }

    struct MasterStructTypeStateVariant<T> {
        vec: Vec<TypeStateVariant<T>>,
    }
    impl MasterStructTypeStateVariant<StructA> {
        pub fn change(&mut self) {
            // this is also changing the generic type of MasterStructTypeStateVariant
            self.vec.iter_mut().for_each(|e| e.change());
        }
        // function definitions become easier :-)
        pub fn do_something(&self) {
            println!("a")
        }
        // this becomes easily possible :-)
        pub fn do_something_for_a(&self) {
            println!("a only")
        }
    }
    impl MasterStructTypeStateVariant<StructB> {
        pub fn do_something(&self) {
            println!("b")
        }
    }

but this is raising

error[E0308]: mismatched types
  --> src\mastermind\mastermind_solver.rs:50:21
   |
50 |             *self = StructB;
   |             -----   ^^^^^^^ expected `TypeStateVariant<StructA>`, found `StructB`
   |             |
   |             expected due to the type of this binding
   |
   = note: expected struct `TypeStateVariant<StructA>`
              found struct `StructB`

It would be possible to do something like

impl TypeStateVariant<StructA> {
        pub fn change(mut self) -> TypeStateVariant<StructB> {
            // how to correctly specify the types?
            TypeStateVariant { val: StructB }
        }
    }
impl MasterStructTypeStateVariant<StructA> {
        pub fn change(&mut self) {
            self.vec = self.vec.drain().map(|e| e.change());
        }
}

which is just shifting this issue one level up.

error[E0308]: mismatched types
  --> src\mastermind\mastermind_solver.rs:65:24
   |
65 |             self.vec = self.vec.drain().map(|e| e.change());
   |             --------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Vec<TypeStateVariant<StructA>>`, found `Map<Drain<'_, ...>, ...>`
   |             |
   |             expected due to the type of this binding
   |
   = note: expected struct `Vec<TypeStateVariant<StructA>>`
              found struct `std::iter::Map<std::vec::Drain<'_, TypeStateVariant<StructA>>, {closure@src\mastermind\mastermind_solver.rs:65:45: 65:48}>`

Is there a better way than creating a function that consumes MasterStructTypeStateVariant and re-creates one with the other type?
...that would totally blow up my use case and not bring any benefit over the enums...

if your collection allows you to store structs at different states then you need a runtime check for what state and element is in (or you could do it with dynamic dispatch but that's probably way messier for almost all scenarios)

in this case typestate pattern cannot reduce boilerplate and will most likely just increase it, it is still potentially useful because it forces you to correctly check the enum variant before a function call.

you will likely end up with something like this

pub struct State1{
       state1_data:u32
}
pub struct State2{
        state2_data:u32
}
pub struct MachineState<State>{
       common:u32
       state_data:State
}
pub enum StateMachine{
    State1(MachineState<State1>)
    State2(MachineState<State2>)
}

impl MachineState<State1>{
      fn change_state(self)->MachineState<State2>{
                MachineState<State2>{
                      common:self.common,
                      state_data:State2{
                              state_2_data:state1_data /2
                       }
                }
       }
}

impl StateMachine{
      pub fn try_from_state1_to_state_2(self)->Result<Self,Self>{
              match self{
                  StateMachine::State1(ms1)=>Ok(StateMachine::State2(ms1.change_state()),
                  other=>Err(other)
             }
      }
     pub fn from_state1_to_state_2_or_panic(self)->Self{
              match self{
                  StateMachine::State1(ms1)=>StateMachine::State2(ms1.change_state(),
                  other=>panic!("incorrect state")
              }
      }
}

wow - that was a quick answer and that's a nice concept. Thanks for the support :slightly_smiling_face:

So the StateMachine takes care of the Type.