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 | 151 |
1 files changed, 3 insertions, 148 deletions
diff --git a/rust_fsm_dsl/src/lib.rs b/rust_fsm_dsl/src/lib.rs index 18b9b00..cfa93b3 100644 --- a/rust_fsm_dsl/src/lib.rs +++ b/rust_fsm_dsl/src/lib.rs @@ -7,154 +7,9 @@ extern crate proc_macro; use proc_macro::TokenStream; use quote::quote; use std::collections::HashSet; -use syn::{ - braced, bracketed, parenthesized, - parse::{Error, Parse, ParseStream, Result}, - parse_macro_input, - token::{Bracket, Paren}, - Ident, Token, Visibility, -}; +use syn::{parse_macro_input, Ident}; -/// The output of a state transition -struct Output(Option<Ident>); - -impl Parse for Output { - fn parse(input: ParseStream) -> Result<Self> { - if input.lookahead1().peek(Bracket) { - let output_content; - bracketed!(output_content in input); - Ok(Self(Some(output_content.parse()?))) - } else { - Ok(Self(None)) - } - } -} - -impl Into<Option<Ident>> for Output { - fn into(self) -> Option<Ident> { - self.0 - } -} - -/// Represents a part of state transition without the initial state. The `Parse` -/// trait is implemented for the compact form. -struct TransitionEntry { - input_value: Ident, - final_state: Ident, - output: Option<Ident>, -} - -impl Parse for TransitionEntry { - fn parse(input: ParseStream) -> Result<Self> { - let input_value = input.parse()?; - input.parse::<Token![=>]>()?; - let final_state = input.parse()?; - let output = input.parse::<Output>()?.into(); - Ok(Self { - input_value, - final_state, - output, - }) - } -} - -/// Parses the transition in any of the possible formats. -struct TransitionDef { - initial_state: Ident, - transitions: Vec<TransitionEntry>, -} - -impl Parse for TransitionDef { - fn parse(input: ParseStream) -> Result<Self> { - let initial_state = input.parse()?; - // Parse the transition in the simple format - // InitialState(Input) => ResultState [Output] - let transitions = if input.lookahead1().peek(Paren) { - let input_content; - parenthesized!(input_content in input); - let input_value = input_content.parse()?; - input.parse::<Token![=>]>()?; - let final_state = input.parse()?; - let output = input.parse::<Output>()?.into(); - - vec![TransitionEntry { - input_value, - final_state, - output, - }] - } else { - // Parse the transition in the compact format - // InitialState => { - // Input1 => State1, - // Input2 => State2 [Output] - // } - input.parse::<Token![=>]>()?; - let entries_content; - braced!(entries_content in input); - - let entries: Vec<_> = entries_content - .parse_terminated::<_, Token![,]>(TransitionEntry::parse)? - .into_iter() - .collect(); - if entries.is_empty() { - return Err(Error::new_spanned( - initial_state, - "No transitions provided for a compact representation", - )); - } - entries - }; - Ok(Self { - initial_state, - transitions, - }) - } -} - -/// Parses the whole state machine definition in the following form (example): -/// -/// ```rust,ignore -/// state_machine! { -/// CircuitBreaker(Closed) -/// -/// Closed(Unsuccessful) => Open [SetupTimer], -/// Open(TimerTriggered) => HalfOpen, -/// HalfOpen => { -/// Successful => Closed, -/// Unsuccessful => Open [SetupTimer] -/// } -/// } -/// ``` -struct StateMachineDef { - /// The visibility modifier (applies to all generated items) - visibility: Visibility, - name: Ident, - initial_state: Ident, - transitions: Vec<TransitionDef>, -} - -impl Parse for StateMachineDef { - fn parse(input: ParseStream) -> Result<Self> { - let visibility = input.parse()?; - let name = input.parse()?; - - let initial_state_content; - parenthesized!(initial_state_content in input); - let initial_state = initial_state_content.parse()?; - - let transitions = input - .parse_terminated::<_, Token![,]>(TransitionDef::parse)? - .into_iter() - .collect(); - - Ok(Self { - visibility, - name, - initial_state, - transitions, - }) - } -} +mod parser; /// The full information about a state transition. Used to unify the /// represantion of the simple and the compact forms. @@ -167,7 +22,7 @@ struct Transition<'a> { #[proc_macro] pub fn state_machine(tokens: TokenStream) -> TokenStream { - let input = parse_macro_input!(tokens as StateMachineDef); + let input = parse_macro_input!(tokens as parser::StateMachineDef); if input.transitions.is_empty() { let output = quote! { |