#状态机 #DSL #rust

fluent_state_machine

用于在 Rust 中创建状态机的领域特定语言 (DSL)

5 个版本 (破坏性)

0.5.0 2024年3月11日
0.4.0 2024年3月11日
0.3.0 2024年3月11日
0.2.0 2024年3月5日
0.1.0 2024年3月5日

#606 in 算法

Download history

每月下载 108

MIT 许可证

12KB
142

状态机 DSL

这是一个提供领域特定语言 (DSL) 以创建状态机的 Rust 项目。

入门指南

以下说明将帮助您在本地机器上复制项目,以便进行开发和测试。

先决条件

您需要在机器上安装 Rust 和 Cargo。如果您还没有安装,可以从 这里 获取它们。

克隆仓库

要克隆仓库,请运行以下命令

git clone https://github.com/hansaskov1/state_machine_dsl.git
cd state_machine_dsl

运行项目

您可以运行三个可用的示例之一 cd_playerturnstile_enumturnstile_str。以下是如何运行 cd_player 示例

cargo run --example cd_player

运行测试

您可以使用以下命令运行测试

cargo test

代码示例

使用字符串字面量创建转闸状态机

fn main() {
    let mut turnstyle = StateMachineBuilder::new((), "Locked")
        .state("Locked")
            .on("Coin").go_to("Unlocked")
        .state("Unlocked")
            .on("Push").go_to("Locked")
        .build().unwrap();

    turnstyle.trigger("Coin");
    println!("State: {}", turnstyle.state);
}

此代码将打印出 State: UnLocked

使用枚举创建转闸状态机

#[derive(Debug, Clone, Copy, PartialEq)]
enum State {
    Locked,
    UnLocked
}

#[derive(PartialEq)]
enum Event {
    Coin,
    Push,
}

fn main() {
    
    let mut turnstyle = StateMachineBuilder::new((), State::Locked)
        .state(State::Locked)
            .on(Event::Coin).go_to(State::UnLocked)
        .state(State::UnLocked)
            .on(Event::Push).go_to(State::Locked)
        .build().unwrap();

    turnstyle.trigger(Event::Coin);
    println!("State: {:?}", turnstyle.state);
}

这也会打印出 "State: UnLocked"

以下是一个更复杂的 Cd-Player 示例

fn main() {

    // Create store for state machine. In this case it is an integer
    let track = 0;
    
    let mut cd_player = StateMachineBuilder::new( track, "Stopped")
        .state("Stopped")
            .on("Play").go_to("Playing").only_if(|track| *track > 0 )
            .on("Forward").update(|track| *track += 1 )
            .on("Backward").update(|track| *track -= 1)
        .state("Playing")
            .on("Stop").go_to("Stopped").then(|track| *track = 0)
            .on("Pause").go_to("Paused")
        .state("Paused")
            .on("Play").go_to("Playing")
            .on("Stop").go_to("Stopped").then(|track| *track = 0)
            .on("Forward").update(|track| *track += 1)
            .on("Backward").update(|track| *track -= 1)
        .build()
        .unwrap();

    println!("Track: {}, State: {}", cd_player.store, cd_player.state);

    cd_player.trigger("Forward");
    println!("Track: {}, State: {}", cd_player.store, cd_player.state);

    cd_player.trigger("Play");
    println!("Track: {}, State: {}", cd_player.store, cd_player.state);
}

运行此示例将给出以下输出:" Track: 0, State: Stopped Track: 1, State: Stopped Track: 1, State: Playing "

无运行时依赖