Finite state machines in rust; bendns fork to add types.
Changed repr_c implementation from a feature to an argument of the state_machine macro
Aaron Jost 2022-10-09
parent 55cc0df · commit d050bbe
-rw-r--r--README.md3
-rw-r--r--rust-fsm-dsl/Cargo.toml5
-rw-r--r--rust-fsm-dsl/src/lib.rs9
-rw-r--r--rust-fsm-dsl/src/parser.rs32
-rw-r--r--rust-fsm/Cargo.toml2
-rw-r--r--rust-fsm/tests/simple.rs1
6 files changed, 43 insertions, 9 deletions
diff --git a/README.md b/README.md
index f55746e..8faaa5b 100644
--- a/README.md
+++ b/README.md
@@ -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,