State machines with enums
User-defined enums lower to tagged Lua tables. Use them for phases, commands,
or any closed set of cases you want to match on - distinct from Factorio API
string unions like GuiDirection.
Define the machine
Section titled “Define the machine”enum Phase { Idle, Mining { ticks: i64 }, Done,}
impl Phase { fn tick(self) -> Phase { match self { Phase::Idle => Phase::Mining { ticks: 0 }, Phase::Mining { ticks } if ticks + 1 >= 60 => Phase::Done, Phase::Mining { ticks } => Phase::Mining { ticks: ticks + 1 }, Phase::Done => Phase::Done, } }}What Lua looks like
Section titled “What Lua looks like”| Rust | Lua shape |
|---|---|
Phase::Idle |
{ tag = "Idle" } |
Phase::Mining { ticks: 3 } |
{ tag = "Mining", ticks = 3 } |
Tuple variant Msg::Move(x, y) |
{ tag = "Move", _1 = x, _2 = y } |
Inherent methods share a table with unit variant constants, like structs.
Drive it from an event
Section titled “Drive it from an event”use factorio_rs::prelude::*;
// Keep the current phase in storage or a local you refresh each event.fn on_tick(phase: Phase) -> Phase { let next = phase.tick(); match &next { Phase::Done => println!("finished"), Phase::Mining { ticks } => println!("mining t={ticks}"), Phase::Idle => {} } next}Persist the phase if it must survive saves - Persist with storage.
API string unions are different
Section titled “API string unions are different”// Factorio literal union -> plain Lua stringlet dir = GuiDirection::Horizontal; // "horizontal"Your enum Phase is a tagged table. Do not mix the two mental models.
Details: Enums.
See also
Section titled “See also”- Supported Rust - pattern rules /
matches! - Option and Result -
Some/Okarms