Closed oblique closed 2 years ago
Let me know if you have any comments
Pushed new changes. I avoided panicking, however fn state
still needs unwrap
, so I used unwrap_unchecked
instead, but I don't like that it is unsafe.
If you have any other ideas let me know.
I had an idea today to introduce Error::Poisoned
. Normally this error should never happen, but it's the only way to avoid unwrap
without unsafe.
These are the reasons that this error will happen:
self.state
to Some
. For example before returning GuardFailed
or InvalidEvent
.self.state
was not restored to Some
.This is the generated code:
#[inline(always)]
pub fn state(&self) -> Result<&States, Error> {
self.state.as_ref().ok_or_else(|| Error::Poisoned)
}
pub fn process_event(&mut self, mut event: Events) -> Result<&States, Error> {
match self.state.take().ok_or_else(|| Error::Poisoned)? {
States::State1 => match event {
Events::Event1(event_data) => {
match self.context.guard1(&event_data) {
Ok(()) => {
let _data = self.context.action1(event_data);
self.state = Some(States::State2(_data));
}
Err(e) => {
self.state = Some(States::State1);
return Err(Error::GuardFailed(e));
}
}
self.state()
}
_ => {
self.state = Some(States::State1);
Err(Error::InvalidEvent)
}
},
States::State2(state_data) => match event {
_ => {
self.state = Some(States::State2(state_data));
Err(Error::InvalidEvent)
}
},
state => {
self.state = Some(state);
Err(Error::InvalidEvent)
}
}
}
Rebased. Now the generated code is:
pub fn state(&self) -> Result<&States, Error> {
self.state.as_ref().ok_or_else(|| Error::Poisoned)
}
pub fn process_event(&mut self, mut event: Events) -> Result<&States, Error> {
match self.state.take().ok_or_else(|| Error::Poisoned)? {
States::State1 => match event {
Events::Event1(event_data) => {
if let Err(e) = self.context.guard1(&event_data) {
self.state = Some(States::State1);
return Err(Error::GuardFailed(e));
}
let _data = self.context.action1(event_data);
self.state = Some(States::State2(_data));
self.state()
}
_ => {
self.state = Some(States::State1);
Err(Error::InvalidEvent)
}
},
States::State2(state_data) => match event {
_ => {
self.state = Some(States::State2(state_data));
Err(Error::InvalidEvent)
}
},
state => {
self.state = Some(state);
Err(Error::InvalidEvent)
}
}
}
Closes #48