Finite state machines in rust; bendns fork to add types.
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | rust-fsm-dsl/Cargo.toml | 5 | ||||
| -rw-r--r-- | rust-fsm-dsl/src/lib.rs | 9 | ||||
| -rw-r--r-- | rust-fsm-dsl/src/parser.rs | 32 | ||||
| -rw-r--r-- | rust-fsm/Cargo.toml | 2 | ||||
| -rw-r--r-- | rust-fsm/tests/simple.rs | 1 |
6 files changed, 43 insertions, 9 deletions
@@ -57,6 +57,7 @@ use rust_fsm::*; state_machine! { derive(Debug) + repr_c(true) CircuitBreaker(Closed) Closed(Unsuccessful) => Open [SetupTimer], @@ -72,6 +73,8 @@ This code sample: * Defines a state machine called `CircuitBreaker`; * Derives the `Debug` trait for it (the `derive` section is optional); +* Adds repr(C) support to generated code for better FFI compatability + (the `repr_c` section is optional and defaults to false); * Sets the initial state of this state machine to `Closed`; * Defines state transitions. For example: on receiving the `Successful` input when in the `HalfOpen` state, the machine must move to the `Closed` diff --git a/rust-fsm-dsl/Cargo.toml b/rust-fsm-dsl/Cargo.toml index 966e818..4803017 100644 --- a/rust-fsm-dsl/Cargo.toml +++ b/rust-fsm-dsl/Cargo.toml @@ -8,7 +8,7 @@ readme = "../README.md" license = "MIT" categories = ["data-structures", "rust-patterns"] keywords = ["fsm"] -version = "0.6.1" +version = "0.6.0" authors = ["Yevhenii Babichenko"] edition = "2018" @@ -18,6 +18,3 @@ proc-macro = true [dependencies] syn = "1" quote = "1" - -[features] -repr_c = [] diff --git a/rust-fsm-dsl/src/lib.rs b/rust-fsm-dsl/src/lib.rs index 07ebb69..ba4ef46 100644 --- a/rust-fsm-dsl/src/lib.rs +++ b/rust-fsm-dsl/src/lib.rs @@ -32,10 +32,11 @@ pub fn state_machine(tokens: TokenStream) -> TokenStream { quote! {} }; - #[cfg(feature = "repr_c")] - let type_repr = quote! { #[repr(C)] }; - #[cfg(not(feature = "repr_c"))] - let type_repr = quote! { }; + let type_repr = if let Some(true) = input.repr_c { + quote! { #[repr(C)] } + } else { + quote! {} + }; if input.transitions.is_empty() { let output = quote! { diff --git a/rust-fsm-dsl/src/parser.rs b/rust-fsm-dsl/src/parser.rs index 25a1283..7ea732d 100644 --- a/rust-fsm-dsl/src/parser.rs +++ b/rust-fsm-dsl/src/parser.rs @@ -7,6 +7,7 @@ use syn::{ mod kw { syn::custom_keyword!(derive); + syn::custom_keyword!(repr_c); } /// The output of a state transition @@ -105,6 +106,34 @@ impl Parse for TransitionDef { } } + +struct ReprC { + repr_c: Option<bool>, +} + +impl Parse for ReprC { + fn parse(input: ParseStream) -> Result<Self> { + let lookahead = input.lookahead1(); + if lookahead.peek(kw::repr_c) { + let kw_repr_c = input.parse::<kw::repr_c>()?; + let entries_content; + parenthesized!(entries_content in input); + match entries_content.parse::<syn::Lit>() { + Ok(syn::Lit::Bool(b)) => { + return Ok( ReprC { + repr_c: Some(b.value()), + }); + }, + _ => { + return Err(Error::new_spanned(kw_repr_c, "Invalid repr_c argument")); + }, + } + } + Ok(ReprC { repr_c: None }) + } +} + + struct Derives { derives: Option<Vec<Ident>>, } @@ -152,11 +181,13 @@ pub struct StateMachineDef { pub initial_state: Ident, pub transitions: Vec<TransitionDef>, pub derives: Option<Vec<Ident>>, + pub repr_c: Option<bool>, } impl Parse for StateMachineDef { fn parse(input: ParseStream) -> Result<Self> { let Derives { derives } = input.parse()?; + let ReprC { repr_c } = input.parse()?; let visibility = input.parse()?; let name = input.parse()?; @@ -176,6 +207,7 @@ impl Parse for StateMachineDef { initial_state, transitions, derives, + repr_c, }) } } diff --git a/rust-fsm/Cargo.toml b/rust-fsm/Cargo.toml index 4301565..82980ba 100644 --- a/rust-fsm/Cargo.toml +++ b/rust-fsm/Cargo.toml @@ -18,7 +18,7 @@ std = [] dsl = ["rust-fsm-dsl"] [dependencies] -rust-fsm-dsl = { path = "../rust-fsm-dsl", version = "0.6.1", optional = true } +rust-fsm-dsl = { path = "../rust-fsm-dsl", version = "0.6.0", optional = true } [profile.dev] panic = "abort" diff --git a/rust-fsm/tests/simple.rs b/rust-fsm/tests/simple.rs index b3fa09c..d889dbb 100644 --- a/rust-fsm/tests/simple.rs +++ b/rust-fsm/tests/simple.rs @@ -2,6 +2,7 @@ use rust_fsm::*; state_machine! { derive(Debug) + repr_c(true) Door(Open) Open(Key) => Closed, |