1个不稳定版本
0.1.0 | 2023年4月17日 |
---|
#712 in 过程宏
12KB
191 行
Rust-FSM
用Rust编写的静态检查有限状态机。
动机
因为可以。并且我想练习在Rust中创建过程宏。这可以很有趣...
用法
要创建状态机,请使用 fsm
宏。
fsm!{
initial = init_state
state_1
state_2
...
end = end_state_1, end_state_2,...
state_n -> state_m: transition_k
...
}
// --snip--
// Initialize the finite state machine
let mut fsm = FSM::new();
// run transition and save new struct
fsm = fsm.transition_k();
let f = |from: &str, to: &str, event: &str| {
println!("from: {from}, to: {to}, event: {event}");
// other actions to be performed
}
// You can pass a callback function to be called with the transition
fsm = fsm.transition_l_fn(f);
// Call the end function. Confirm that the FSM reached a final state.
fsm.end();
// or pass a closure
f_end = |state: %str| {
println!("done!");
// maybe do something else as well...
}
fsm.end_fn(f_end);
它是如何工作的
宏为所有状态创建类型和一个FSM结构体。FSM结构体是用户应该使用的。状态类型允许它定义和限制可以调用哪些转换/函数。
生成的示例代码
type struct state_1;
...
type struct FSM<T> {
...
pub history: Vec<Transition>,
}
type struct Transition{
pub from: String,
pub to: String,
pub event: string,
}
impl FSM {
pub fn new() -> FSM<initial_state> {
return FSM{
// initialization here
}
}
}
impl FSM<state_1> {
pub fn transition_k(self) -> FSM<state_2> {
return FSM {
// initialization here as well
}
}
pub fn transition_k_fn(self, f: Fn(&str, &str, &str)) -> FSM<state_2> {
f("state_1", "state_2", "transition_k");
return self.transition_k();
}
}
...
impl FSM<end_state> {
...
// note that it destroys the object.
// Do what you want with it before calling this function
pub fn end() {}
pub fn end_fn(f: Fn(&str)) {
f("end_state");
}
}
问题
- 净化
- 生成的代码放置在宏调用相同的模块中。理想情况下,它应该创建一个新的模块并将新的结构体放在那里。
- 宏和LSP
- 宏的LSP支持不是很好。不一定提供智能提示,可能不会警告关于坏代码。
要添加的功能
- 提供将FSM打印为图形格式的函数
- 目前可能将继续使用dot
- 检查不可达状态
- 应该给出某种警告...
- 允许同一行有多个转换标签
- 例如:
A -> B: a,b,c,...
- 例如:
依赖项
~1.3–9.5MB
~85K SLoC