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 | 43 |
1 files changed, 18 insertions, 25 deletions
diff --git a/rust-fsm-dsl/src/lib.rs b/rust-fsm-dsl/src/lib.rs index 8bd6e18..1b25fba 100644 --- a/rust-fsm-dsl/src/lib.rs +++ b/rust-fsm-dsl/src/lib.rs @@ -6,7 +6,6 @@ extern crate proc_macro; use proc_macro::TokenStream; use quote::{quote, ToTokens}; -use std::iter::FromIterator; use syn::*; mod parser; mod variant; @@ -24,7 +23,7 @@ struct Transition<'a> { fn attrs_to_token_stream(attrs: Vec<Attribute>) -> proc_macro2::TokenStream { let attrs = attrs.into_iter().map(ToTokens::into_token_stream); - proc_macro2::TokenStream::from_iter(attrs) + attrs.collect() } #[proc_macro] @@ -67,7 +66,6 @@ pub fn state_machine(tokens: TokenStream) -> TokenStream { let mut inputs = vec![]; let mut outputs = vec![]; let mut transition_cases = vec![]; - let mut output_cases = vec![]; #[cfg(feature = "diagram")] let mut mermaid_diagram = format!( @@ -126,24 +124,22 @@ pub fn state_machine(tokens: TokenStream) -> TokenStream { // let input_ = input_value.match_on(); // let final_state_ = final_state.match_on(); + let output_ = output + .as_ref() + .map(|x| { + #[cfg(feature = "diagram")] + mermaid_diagram.push_str(&format!(" [\"{x}\"]")); + let output = x.reduce(); + quote! { ::core::option::Option::Some(Self::Output::#output) } + }) + .unwrap_or(quote! { ::core::option::Option::None }); + // let x = format!("{}, {} {} => {}", initial_, input_, guard, output_); transition_cases.push(quote! { (Self::#initial_, Self::Input::#input_) #guard => { - Some(Self::#final_) + ::core::result::Result::Ok((Self::#final_, #output_)) } }); - if let Some(output_value) = output { - let output_ = output_value.reduce(); - output_cases.push(quote! { - (Self::#initial_, Self::Input::#input_) #guard => { - Some(Self::Output::#output_) - } - }); - - #[cfg(feature = "diagram")] - mermaid_diagram.push_str(&format!(" [\"{output_value}\"]")); - } - #[cfg(feature = "diagram")] mermaid_diagram.push('\n'); @@ -191,7 +187,7 @@ pub fn state_machine(tokens: TokenStream) -> TokenStream { }) }); let state_name = state_name.path(); - let output_impl = variant::tokenize(&*outputs, |outputs| { + let output_impl = variant::tokenize(&outputs, |outputs| { output_name.tokenize(|output_name| { // 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. @@ -231,19 +227,16 @@ pub fn state_machine(tokens: TokenStream) -> TokenStream { type Input = #input_name; type Output = #output_name; - fn transition(self, input: Self::Input) -> Option<Self> { + fn transition(self, input: Self::Input) -> ::core::result::Result< + (Self, ::core::option::Option<Self::Output>), + ::rust_fsm::TransitionImpossibleError<Self, Self::Input> + > { match (self, input) { #(#transition_cases)* - _ => None, + (state, input) => ::core::result::Result::Err(::rust_fsm::TransitionImpossibleError { state, input, }), } } - fn output(self, input: Self::Input) -> Option<Self::Output> { - match (self, input) { - #(#output_cases)* - _ => None, - } - } } }; |