I'm trying out this nice state machine library at https://github.com/rust-bakery/machine.
It complains about:
--> src/main.rs:27:15
|
27 | (IsTaken, DropItem) => IsDropped,
| ^^^^^^^^ expected lifetime parameter
because the struct DropItem is apparently not allowed to have lifetime references, maybe a limitation of the library. The mutable reference is called bang and I'd like to have it available on transition.
Using a second parameter for IsTaken::on_drop_item also errors out.
Is there a way to use mutable references in this case for messages/state change at all?
The last resort would be to kill the macros and write everything by hand.
My code: (playground does not compile because it's missing the lib called machine
)
#[macro_use]
extern crate machine;
enum State {
TakeItem,
DropItem,
}
machine!(
#[derive(Clone,Debug,PartialEq)]
enum Weight {
IsTaken { weight: usize },
IsDropped,
}
);
#[derive(Clone,Debug,PartialEq)]
//pub struct DropItem; //without reference
pub struct DropItem<'a> { //this does not work
bang: &'a mut Bang,
}
#[derive(Clone,Debug,PartialEq)]
pub struct TakeItem;
transitions!(Weight,
[
(IsTaken, DropItem) => IsDropped,
(IsDropped, DropItem) => IsDropped,
(IsDropped, TakeItem) => IsTaken,
(IsTaken, TakeItem) => IsTaken
]
);
impl IsTaken {
pub fn on_drop_item(self, message: DropItem) -> IsDropped {
//pub fn on_drop_item(self, message: DropItem, bang: &mut Bang) -> IsDropped {
//message.bang can be used here...
println!("drops weight {}", self.weight);
IsDropped {}
}
pub fn on_take_item(self, _: TakeItem) -> IsTaken {
self
}
}
impl IsDropped {
pub fn on_take_item(self, _: TakeItem) -> IsTaken {
let weight = 24;//@fixme set real value here
println!("takes weight {}", weight);
IsTaken {
weight
}
}
pub fn on_drop_item(self, _: DropItem) -> IsDropped {
self
}
}
impl Weight {
fn new() -> Self {
Weight::IsDropped(IsDropped{})
}
fn step(self, state: State, bang: &mut Bang) -> Weight {
let next = match state {
State::TakeItem{} => {
self.on_take_item(TakeItem)
},
State::DropItem => {
self.on_drop_item(DropItem{ bang })
},
};
if next == Weight::error()
{
//reset machine
return next.on_drop_item(DropItem{ bang })
}
next
}
}
struct Bang {}
fn main() {
let mut t = Weight::new();
assert_eq!(t, Weight::isdropped());
let mut bang = Bang {};
t = t.step(State::TakeItem, &mut bang);
assert_eq!(t, Weight::istaken(24));
t = t.step(State::TakeItem, &mut bang);
assert_eq!(t, Weight::istaken(24));
t = t.step(State::DropItem, &mut bang);
assert_eq!(t, Weight::isdropped());
t = t.step(State::DropItem, &mut bang);
assert_eq!(t, Weight::isdropped());
}
Thank you