Skip to content

Commit 9df1e6f

Browse files
committed
Implement guard expressions
1 parent f199304 commit 9df1e6f

File tree

14 files changed

+203
-180
lines changed

14 files changed

+203
-180
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog][keepachangelog], and this project
55
adheres to [Semantic Versioning][semver].
66

7+
8+
## [0.0.3] - 2025-04-26
9+
### Update
10+
* Improve error messages.
11+
* Add support for guards expressions.
12+
* strum_macros is no longer a dependency.
13+
* Nicer mermaid diagrams for self-transitions.
14+
* Dropped `dot` feature due to ugly output.
15+
716
## [0.0.2] - 2025-04-23
817
### Update
918
* Improve documentation.

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ test:
55
TMPDIR=~/tmp cargo test
66

77
doc:
8-
RUSTDOCFLAGS="--html-in-header ./examples/assets/graphviz-header.html" cargo doc --no-deps --document-private-items
8+
cargo doc --no-deps --document-private-items
99

1010
doc-open:
11-
RUSTDOCFLAGS="--html-in-header ./examples/assets/graphviz-header.html" cargo doc --no-deps --document-private-items--open
11+
cargo doc --no-deps --document-private-items--open
1212

1313
clean:
1414
cargo clean

README.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,12 @@ Major:
109109
- [ ] Add support for capturing traces of the machine and replaying them.
110110

111111
Minor (soon):
112-
- [ ] Guards as bool expressions
112+
- [x] Guards as bool expressions
113+
- [ ] Performance improvements
113114
- [ ] Logging transitions -- tracing?
114-
- [ ] Configurable `should_panic` for invalid transitions
115+
- [ ] Configurable `should_panic` for invalid transitions
115116
- [ ] Better error messages
116117
- sig checks for guards
117-
- `dont_expand` for debugging
118-
- [ ] Reconsider if handlers should get mut self, based on usage examples.
119-
- [ ] better doc links, nicer dot links
120118

121119
## Contributions are welcome!
122120

@@ -131,7 +129,6 @@ Also, I'd be happy if you star the repo!
131129
## Feature flags
132130

133131
- `mermaid` - generate Mermaid state diagrams in the doc strings.
134-
- `dot` - generate DOT state diagrams in the doc strings.
135132
- `dsl` (default) - re-export the DSL into doc strings.
136133

137134
## Without DSL

examples/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7-
rust-automata = { path = "../rust-automata", version = "0.0.2", features = ["mermaid", "dot", "dsl"] }
7+
rust-automata = { path = "../rust-automata", version = "0.0.3", features = ["mermaid", "dsl"] }

examples/assets/graphviz-header.html

Lines changed: 0 additions & 21 deletions
This file was deleted.

examples/src/circuit_breaker.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ pub mod inputs {
8484
(states::Closed, inputs::Fail) -> (states::Closed) : guard_below_threshold = handle_count_increment,
8585
(states::Closed, inputs::Fail) -> (states::Open) : guard_not_below_threshold = handle_trip_breaker,
8686
87-
(states::Open) -> (states::Open) : guard_not_timeout,
87+
(states::Open) -> (states::Open) : !guard_timeout,
8888
(states::Open) -> (states::HalfOpen) : guard_timeout,
8989
9090
(states::HalfOpen, inputs::Fail) -> (states::Open) = handle_setup_timer,
@@ -108,13 +108,14 @@ impl CircuitBreaker {
108108
fn guard_not_below_threshold(&self, closed: &states::Closed) -> bool {
109109
closed.count >= self.threshold
110110
}
111-
fn guard_not_timeout(&self, open: &states::Open) -> bool {
112-
!open.timer.is_timeout()
113-
}
114111
fn handle_count_reset(&mut self, _: states::Closed, _: inputs::Success) -> states::Closed {
115112
states::Closed { count: 0 }
116113
}
117-
fn handle_count_increment(&mut self, closed: states::Closed, _: inputs::Fail) -> states::Closed {
114+
fn handle_count_increment(
115+
&mut self,
116+
closed: states::Closed,
117+
_: inputs::Fail,
118+
) -> states::Closed {
118119
states::Closed {
119120
count: closed.count + 1,
120121
}

rust-automata-macros/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ readme = "README.md"
88
license = "MIT"
99
categories = ["data-structures", "rust-patterns"]
1010
keywords = ["fsm", "automata", "state", "machine"]
11-
version = "0.0.2"
11+
version = "0.0.3"
1212
authors = ["Michal Sustr"]
1313
edition = "2021"
1414

@@ -17,7 +17,6 @@ proc-macro = true
1717

1818
[features]
1919
mermaid = []
20-
dot = []
2120
dsl = []
2221

2322
[dependencies]

rust-automata-macros/src/annotations/dot.rs

Lines changed: 0 additions & 90 deletions
This file was deleted.

rust-automata-macros/src/annotations/dsl.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use quote::quote;
44

55
#[cfg(feature = "dsl")]
66
pub fn attr(m: &parser::MachineAttr) -> TokenStream2 {
7+
use crate::parser::guard_expr_to_string;
78
use crate::util;
89
use crate::util::key;
910
use std::fmt::Write;
@@ -113,7 +114,12 @@ pub fn attr(m: &parser::MachineAttr) -> TokenStream2 {
113114

114115
// Add guard if present
115116
if let Some(ref guard) = tr.guard {
116-
write!(dsl, " : {}", guard).unwrap();
117+
write!(
118+
dsl,
119+
" : {}",
120+
guard_expr_to_string(guard, &|path| util::key(path))
121+
)
122+
.unwrap();
117123
}
118124

119125
// Add handler if present

rust-automata-macros/src/annotations/mermaid.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ use quote::quote;
55
#[cfg(feature = "mermaid")]
66
fn transition_label(tr: &parser::Transition) -> String {
77
use crate::annotations::doc_link;
8+
use crate::parser::guard_expr_to_string;
89
use crate::util;
910
use crate::GUARD_PREFIX;
1011
use crate::HANDLE_PREFIX;
11-
1212
let mut label = String::new();
1313
if let Some(ref i) = tr.input {
1414
let ev = util::last(i);
@@ -24,15 +24,23 @@ fn transition_label(tr: &parser::Transition) -> String {
2424
));
2525
}
2626
if let Some(ref g) = tr.guard {
27+
let guard_str = guard_expr_to_string(g, &|path| {
28+
let guard_id = util::key(path);
29+
format!(
30+
"<a href='#method.{}'>{}</a>",
31+
guard_id,
32+
guard_id.replace(GUARD_PREFIX, "")
33+
)
34+
});
2735
label.push_str(&format!(
28-
"{0}&nbsp;<a href='#method.{g}'>{1}</a>",
36+
"{0}&nbsp;{1}",
2937
if label.is_empty() { "" } else { "<br>" },
30-
g.to_string().replace(GUARD_PREFIX, "")
38+
guard_str
3139
));
3240
}
3341
if let Some(ref h) = tr.handler {
3442
label.push_str(&format!(
35-
"{0}&nbsp;<a href='#method.{h}'>{1}</a>",
43+
"{0}↪️&nbsp;<a href='#method.{h}'>{1}</a>",
3644
if label.is_empty() { "" } else { "<br>" },
3745
h.to_string().replace(HANDLE_PREFIX, "")
3846
));
@@ -53,7 +61,11 @@ pub fn attr(m: &parser::MachineAttr) -> TokenStream2 {
5361
let mut md = String::new();
5462
writeln!(md, "///```mermaid").unwrap();
5563
writeln!(md, "///stateDiagram-v2").unwrap();
56-
writeln!(md, "/// classDef selfLoop fill:#eee,stroke-width:0px,shape:rectangle,margin:0,padding:0").unwrap();
64+
writeln!(
65+
md,
66+
"/// classDef selfLoop fill:#eee,stroke-width:0px,shape:rectangle,margin:0,padding:0"
67+
)
68+
.unwrap();
5769
writeln!(md, "/// [*] --> {}", initial).unwrap();
5870

5971
// Clickable state aliases

0 commit comments

Comments
 (0)