Gust
A type-safe state machine language that compiles to Rust and Go.
Write your state machines once in .gu files. Gust generates idiomatic, production-ready code for your target language. No boilerplate. No invalid states. No hidden side effects.
Why Gust?
Most production bugs aren't algorithm bugs — they're state management bugs, unhandled edge cases at service boundaries, and functions that secretly talk to the database. Gust makes those structurally impossible.
- Describe the state machine in 30 lines, get 300+ lines of correct code out
- Change a state or transition, regenerate — no hunting through match arms
- Same
.gufile targets Rust and Go — your service contract is language-agnostic
Core Concepts
| Concept | Description |
|---|---|
| Algebraic State Machines | Define states and transitions declaratively. The compiler enforces that only valid transitions can occur. |
| Effect Tracking | Side effects (IO, network, database) are declared as effects. You know at a glance what a function does. |
| Auto Serialization | Rust output derives Serialize/Deserialize. Go output gets json struct tags. |
| Multi-Target | Same .gu source compiles to idiomatic Rust or Go. |
Quick Start
# Build the compiler
# Compile to Rust (default) — outputs .g.rs alongside the .gu file
# Compile to Go
# Watch for changes and rebuild
# Format .gu files
# Validate without generating code
# Generate Mermaid state diagram
Syntax Overview
type Order {
id: String,
customer: String,
}
machine OrderProcessor {
state Pending(order: Order)
state Validated(order: Order, total: Money)
state Failed(reason: String)
transition validate: Pending -> Validated | Failed
effect calculate_total(order: Order) -> Money
on validate(ctx: ValidationCtx) {
let total = perform calculate_total(ctx.order);
if total.cents > 0 {
goto Validated(ctx.order, total);
} else {
goto Failed("invalid total");
}
}
}
Gust generates:
- Rust: State enum, machine struct, transition methods with
matchexhaustiveness, effect trait, serde derives - Go: State constants via
iota, per-state data structs, transition methods with runtime validation, effects interface, json struct tags
File Convention
Generated files use the .g.rs / .g.go extension (inspired by C# source generators):
src/
order_processor.gu # Gust source (you write this)
order_processor.g.rs # Generated Rust (don't edit)
order_processor.g.go # Generated Go (don't edit)
effects.rs # Your effect implementations (you write this)
Architecture
source.gu -> Parser -> AST -> Validator -> RustCodegen -> .g.rs
-> GoCodegen -> .g.go
| Crate | Purpose |
|---|---|
gust-lang |
Parser (pest PEG grammar), AST, validator, Rust and Go code generators |
gust-runtime |
Runtime traits and utilities imported by generated Rust code |
gust-cli |
The gust command-line tool |
gust-lsp |
Language Server Protocol implementation for editor support |
gust-mcp |
Model Context Protocol server for AI-assisted Gust development |
gust-build |
Cargo build script integration (build.rs) |
gust-stdlib |
Standard library of reusable .gu machines |
Editor Support
VS Code
The Gust VS Code extension provides:
- Syntax highlighting for
.gufiles - Diagnostics (errors and warnings)
- Hover documentation
- Go-to-definition
- Format on save
- Custom file icon
v0.1.0 intentionally does not advertise rename or find-references in the LSP because symbol resolution is not yet scope-aware enough to do those edits safely.
Language Keywords
| Keyword | Purpose |
|---|---|
machine |
Declare a state machine |
state |
Declare a state with optional typed fields |
transition |
Declare a valid state transition (from -> targets) |
effect |
Declare a tracked side effect with signature |
on |
Handle a transition with logic |
goto |
Transition to a new state with field values |
perform |
Execute a tracked effect (usable as expression) |
type |
Declare a data type (struct) |
enum |
Declare a sum type |
use |
Import a module |
match |
Pattern match on values |
if/else |
Conditional logic |
let |
Variable binding |
async |
Mark handlers and effects as asynchronous |
Release Status
v0.1.0 — initial public release.
- PEG grammar, parser, AST
- Rust and Go code generation
- Multi-target CLI (
parse,build,watch,init,fmt,check,diagram) -
gust-buildCargo integration - Diagnostics and validation with suggestions
- Async handlers/effects, enums, tuples,
match - Channels, supervision, lifecycle timeouts
- Additional targets (
wasm,nostd,ffi) - LSP with hover, diagnostics, go-to-definition, formatting
- VS Code extension with syntax highlighting and file icon
- MCP server for AI-assisted development
- Standard library (
gust-stdlib) - Documentation book (mdBook)
See ROADMAP.md for what's next.
Known Limitations
- Inter-machine communication is currently local in-process channels only. Network transport is intentionally deferred.
- Cross-file
usedeclarations resolve types but cross-file go-to-definition in the LSP is not yet implemented. - LSP rename and find-references are disabled in
v0.1.0until symbol resolution becomes scope-aware enough to avoid unsafe textual edits. - Context field (
ctx.field) error locations point to the handler declaration rather than the exact field access expression.
Contributing
See CONTRIBUTING.md for setup, required validation commands, and PR expectations.