3 个不稳定版本
0.2.0 | 2021 年 8 月 26 日 |
---|---|
0.1.1 | 2021 年 8 月 21 日 |
0.1.0 | 2021 年 8 月 21 日 |
#2017 在 算法 中
每月 29 次下载
12KB
147 行
step-machine
将您的 CLI 程序作为具有持久化和恢复功能的状态机运行。当此类程序出错时,您将有机会改变外部世界(创建缺失的文件夹、更改文件权限等)并从中断的地方继续程序。
用法
让我们抛两个硬币并确保它们都落在同一面。我们用我们机器的两个状态来表示这种行为。步进逻辑在 State::next()
方法中实现,这些方法返回下一个状态或 None
表示最后一个步骤(完整代码在 examples/coin.rs
中)。
#[derive(Debug, Serialize, Deserialize, From)]
enum Machine {
FirstToss(FirstToss),
SecondToss(SecondToss),
}
#[derive(Debug, Serialize, Deserialize)]
struct FirstToss;
impl FirstToss {
fn next(self) -> StepResult {
let first_coin = Coin::toss();
println!("First coin: {:?}", first_coin);
Ok(Some(SecondToss { first_coin }.into()))
}
}
#[derive(Debug, Serialize, Deserialize)]
struct SecondToss {
first_coin: Coin,
}
impl SecondToss {
fn next(self) -> StepResult {
let second_coin = Coin::toss();
println!("Second coin: {:?}", second_coin);
ensure!(second_coin == self.first_coin, "Coins landed differently");
println!("Coins match");
Ok(None)
}
}
然后我们这样启动我们的机器
let init_state = FirstToss.into();
let mut engine = Engine::<Machine>::new(init_state)?.restore()?;
engine.drop_error()?;
engine.run()?;
我们用第一步初始化 Engine
。然后如果进程被中断(例如,由于错误),则恢复之前的状态。然后我们丢弃可能出现的错误并运行所有步骤直到完成。
现在我们来运行它
$ cargo run --example coin
First coin: Heads
Second coin: Tails
Error: Coins landed differently
这次我们运气不好,程序出现了错误。让我们再试一次
$ cargo run --example coin
Second coin: Heads
Coins match
注意,由于 restore()
的作用,我们的机器从中断的地方继续运行,并知道第一枚硬币落在正面。
依赖项
~0.7–1.5MB
~34K SLoC