Finite state machines in rust; bendns fork to add types.
doc processing
Yevhenii Babichenko 2024-05-13
parent 8750546 · commit 4a66861
-rw-r--r--CHANGELOG.md1
-rw-r--r--Cargo.toml2
-rw-r--r--README.md7
-rw-r--r--doc-example/Cargo.toml7
-rw-r--r--doc-example/src/lib.rs15
-rw-r--r--rust-fsm-dsl/src/lib.rs15
-rw-r--r--rust-fsm-dsl/src/parser.rs6
7 files changed, 46 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e32578..fba31da 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,7 @@ adheres to [Semantic Versioning][semver].
generated inside the said module.
* Supplying ones own enums for state, input and output in the proc-macro (#10).
* An optional possibility to generate Mermaid diagrams.
+* Processing doc comments to generate the state machine module documentation.
## [0.6.2] - 2024-05-11
### Changed
diff --git a/Cargo.toml b/Cargo.toml
index e9fcc18..d75027d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,3 +1,3 @@
[workspace]
resolver = "2"
-members = ["rust-fsm", "rust-fsm-dsl"]
+members = ["rust-fsm", "rust-fsm-dsl", "doc-example"]
diff --git a/README.md b/README.md
index 8d44c06..e4a728b 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,7 @@ use rust_fsm::*;
state_machine! {
#[derive(Debug)]
#[repr(C)]
+ /// A Circuit Breaker state machine.
circuit_breaker(Closed)
Closed(Unsuccessful) => Open [SetupTimer],
@@ -198,6 +199,12 @@ controlled by the `diagram` feature, which is non-default. The diagrams are
generated in the [Mermaid][mermaid] format. This feature includes the Mermaid
script into the documentation page.
+To see this in action, download the repository and run:
+
+```bash
+cargo doc -p doc-example --open
+```
+
### Without DSL
The `state_machine` macro has limited capabilities (for example, a state
diff --git a/doc-example/Cargo.toml b/doc-example/Cargo.toml
new file mode 100644
index 0000000..85693d0
--- /dev/null
+++ b/doc-example/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "doc-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+rust-fsm = { path = "../rust-fsm", version = "0.6.2", features = ["diagram"] }
diff --git a/doc-example/src/lib.rs b/doc-example/src/lib.rs
new file mode 100644
index 0000000..18c0978
--- /dev/null
+++ b/doc-example/src/lib.rs
@@ -0,0 +1,15 @@
+use rust_fsm::state_machine;
+
+state_machine! {
+ /// A dummy implementation of the Circuit Breaker pattern to demonstrate
+ /// capabilities of its library DSL for defining finite state machines.
+ /// https://martinfowler.com/bliki/CircuitBreaker.html
+ pub circuit_breaker(Closed)
+
+ Closed(Unsuccessful) => Open [SetupTimer],
+ Open(TimerTriggered) => HalfOpen,
+ HalfOpen => {
+ Successful => Closed,
+ Unsuccessful => Open [SetupTimer]
+ }
+}
diff --git a/rust-fsm-dsl/src/lib.rs b/rust-fsm-dsl/src/lib.rs
index cc11d31..ea0400e 100644
--- a/rust-fsm-dsl/src/lib.rs
+++ b/rust-fsm-dsl/src/lib.rs
@@ -7,7 +7,7 @@ extern crate proc_macro;
use proc_macro::TokenStream;
use quote::{quote, ToTokens};
use std::{collections::BTreeSet, iter::FromIterator};
-use syn::{parse_macro_input, Ident};
+use syn::{parse_macro_input, Attribute, Ident};
mod parser;
@@ -20,17 +20,19 @@ struct Transition<'a> {
output: &'a Option<Ident>,
}
+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)
+}
+
#[proc_macro]
/// Produce a state machine definition from the provided `rust-fmt` DSL
/// description.
pub fn state_machine(tokens: TokenStream) -> TokenStream {
let input = parse_macro_input!(tokens as parser::StateMachineDef);
- let attrs = input
- .attributes
- .into_iter()
- .map(ToTokens::into_token_stream);
- let attrs = proc_macro2::TokenStream::from_iter(attrs);
+ let doc = attrs_to_token_stream(input.doc);
+ let attrs = attrs_to_token_stream(input.attributes);
if input.transitions.is_empty() {
let output = quote! {
@@ -171,6 +173,7 @@ pub fn state_machine(tokens: TokenStream) -> TokenStream {
let diagram = quote!();
let output = quote! {
+ #doc
#diagram
#visibility mod #fsm_name {
#attrs
diff --git a/rust-fsm-dsl/src/parser.rs b/rust-fsm-dsl/src/parser.rs
index 7b97a03..d4a9c2e 100644
--- a/rust-fsm-dsl/src/parser.rs
+++ b/rust-fsm-dsl/src/parser.rs
@@ -116,6 +116,7 @@ impl Parse for TransitionDef {
/// }
/// ```
pub struct StateMachineDef {
+ pub doc: Vec<Attribute>,
/// The visibility modifier (applies to all generated items)
pub visibility: Visibility,
pub name: Ident,
@@ -130,12 +131,16 @@ pub struct StateMachineDef {
impl Parse for StateMachineDef {
fn parse(input: ParseStream) -> Result<Self> {
let mut state_machine_attributes = Vec::new();
+ let mut doc = Vec::new();
let attributes = Attribute::parse_outer(input)?
.into_iter()
.filter_map(|attribute| {
if attribute.path().is_ident("state_machine") {
state_machine_attributes.push(attribute);
None
+ } else if attribute.path().is_ident("doc") {
+ doc.push(attribute);
+ None
} else {
Some(attribute)
}
@@ -177,6 +182,7 @@ impl Parse for StateMachineDef {
.collect();
Ok(Self {
+ doc,
visibility,
name,
initial_state,