use statemachine_macro::*; statemachine! { struct Foo { counter: usize, traitor: bool } enum FooState consumes [char] from Start accepts [Start]; Start => { @loop => self.counter += 1, @enter => panic!("Look who returned!"), @leave => self.traitor = true, char match 'x' => Secret, _ => Start }, Secret => { _ => Start } } #[test] fn can_create() { let _foo: Foo = statemachine_new!(Foo{ counter: 0, traitor: false }); } #[test] fn looping_does_not_enter() { let mut foo: Foo = statemachine_new!(Foo{ counter: 0, traitor: false }); foo.consume('a'); } #[test] fn looping_counts() { let mut foo: Foo = statemachine_new!(Foo{ counter: 0, traitor: false }); for i in 0..100 { assert_eq!(i, foo.counter); foo.consume('a'); assert_eq!(i + 1, foo.counter); } } #[test] fn looping_does_not_leave() { let mut foo: Foo = statemachine_new!(Foo{ counter: 0, traitor: false }); assert!(!foo.traitor); foo.consume('a'); assert!(!foo.traitor); } #[test] #[should_panic] fn reentering_panics() { let mut foo: Foo = statemachine_new!(Foo{ counter: 0, traitor: false }); foo.consume('a'); foo.consume('x'); foo.consume('a'); } #[test] fn leaving_is_noticed() { let mut foo: Foo = statemachine_new!(Foo{ counter: 0, traitor: false }); assert!(!foo.traitor); foo.consume('a'); assert!(!foo.traitor); foo.consume('x'); assert!(foo.traitor); }