Finite state machines in rust; bendns fork to add types.
Diffstat (limited to 'rust-fsm-dsl/src/lib.rs')
| -rw-r--r-- | rust-fsm-dsl/src/lib.rs | 86 |
1 files changed, 57 insertions, 29 deletions
diff --git a/rust-fsm-dsl/src/lib.rs b/rust-fsm-dsl/src/lib.rs index ce1e5b5..7bed6d9 100644 --- a/rust-fsm-dsl/src/lib.rs +++ b/rust-fsm-dsl/src/lib.rs @@ -78,8 +78,8 @@ pub fn state_machine(tokens: TokenStream) -> TokenStream { let input_value = &transition.input_value; let final_state = &transition.final_state; transition_cases.push(quote! { - (State::#initial_state, Input::#input_value) => { - Some(State::#final_state) + (Self::State::#initial_state, Self::Input::#input_value) => { + Some(Self::State::#final_state) } }); } @@ -90,20 +90,59 @@ pub fn state_machine(tokens: TokenStream) -> TokenStream { let initial_state = &transition.initial_state; let input_value = &transition.input_value; output_cases.push(quote! { - (State::#initial_state, Input::#input_value) => { - Some(Output::#output_value) + (Self::State::#initial_state, Self::Input::#input_value) => { + Some(Self::Output::#output_value) } }); } } - // Many attrs and derives may work incorrectly (or simply not work) for - // empty enums, so we just skip them altogether if the output alphabet is - // empty. - let output_attrs = if outputs.is_empty() { - quote!() - } else { - attrs.clone() + let (input_type, input_impl) = match input.input_type { + Some(t) => (quote!(#t), quote!()), + None => ( + quote!(Input), + quote! { + #attrs + pub enum Input { + #(#inputs),* + } + }, + ), + }; + + let (state_type, state_impl) = match input.state_type { + Some(t) => (quote!(#t), quote!()), + None => ( + quote!(State), + quote! { + #attrs + pub enum State { + #(#states),* + } + }, + ), + }; + + let (output_type, output_impl) = match input.output_type { + Some(t) => (quote!(#t), quote!()), + None => { + // Many attrs and derives may work incorrectly (or simply not work) for empty enums, so we just skip them + // altogether if the output alphabet is empty. + let attrs = if outputs.is_empty() { + quote!() + } else { + attrs.clone() + }; + ( + quote!(Output), + quote! { + #attrs + pub enum Output { + #(#outputs),* + } + }, + ) + } }; let output = quote! { @@ -113,26 +152,15 @@ pub fn state_machine(tokens: TokenStream) -> TokenStream { pub type StateMachine = rust_fsm::StateMachine<Impl>; - #attrs - pub enum Input { - #(#inputs),* - } - - #attrs - pub enum State { - #(#states),* - } - - #output_attrs - pub enum Output { - #(#outputs),* - } + #input_impl + #state_impl + #output_impl impl rust_fsm::StateMachineImpl for Impl { - type Input = Input; - type State = State; - type Output = Output; - const INITIAL_STATE: Self::State = State::#initial_state_name; + type Input = #input_type; + type State = #state_type; + type Output = #output_type; + const INITIAL_STATE: Self::State = Self::State::#initial_state_name; fn transition(state: &Self::State, input: &Self::Input) -> Option<Self::State> { match (state, input) { |