Aasm.cr
:arrows_clockwise: Easy to use finite state machine for Crystal classes
Install / Use
/learn @veelenga/Aasm.crREADME
aasm.cr
Aasm stands for "Acts As State Machine" which means that some abstract object can act as a finite state machine and can be in one of a finite number of states at a time; can change one state to another when initiated by a triggering event.
Getting Started
Adding a state machine to a Crystal class is as simple as including AASM module and writing act_as_state_machine method where you can define states and events with their transitions:
class Transaction
include AASM
def act_as_state_machine
aasm.state :pending, initial: true
aasm.state :active, enter: -> { puts "Just got activated" }
aasm.state :completed
aasm.event :activate do |e|
e.transitions from: :pending, to: :active
end
aasm.event :complete do |e|
e.transitions from: :active, to: :completed
end
end
end
t = Transaction.new.tap &.act_as_state_machine
t.state #=> :pending
t.next_state #=> :active
t.fire :activate # Just got activated
t.state #=> :active
t.next_state #=> :completed
States
State can be defined using aasm.state method passing the name and options:
aasm.state :passive, initial: true
State options
Currently state supports the following options:
initial:Booloptional - indicates whether this state is initial or not. If initial state not specified, first one will be considered as initialguard:(-> Bool)optional - a callback, that gets evaluated once state is getting entered. State will not enter if guard returns falseenter:(->)optional - a hook, that gets evaluated once state entered.
Events
Event can be defined using aasm.state method passing the name and a block with transitions:
aasm.event :delete do |e|
e.transitions from: :active, to: :deleted
end
Event has to be defined after state definition. In other case NoSuchStateException will be raise.
Event options
Currently event supports the following options:
before:(->)optional - a callback, that gets evaluated once before changing a stateafter:(->)optional - a callback, that gets evaluated once after changing a state.
Transitions
Transition can be defined on event with transitions method passing options:
aasm.event :complete do |e|
e.transitions from: [:pending, :active], to: :deleted
end
Transition options
Currently transition supports the following options:
from:(Symbol | Array(Symbol))required - state (or states) from which state of state machine can be changed when event firedto:Symbolrequired - state to which state of state machine will change when event fired.
More examples
One state machine (circular)
class CircularStateMachine
include AASM
def act_as_state_machine
aasm.state :started
aasm.event :restart do |e|
e.transitions from: :started, to: :started
end
end
end
Two states machine
class TwoStateMachine
include AASM
def act_as_state_machine
assm.state :active
aasm.state :deleted
aasm.event :delete do |e|
e.transitions from: :active, to: :deleted
end
end
end
Three states machine
class ThreeStatesMachine
include AASM
def act_as_state_machine
aasm.state :pending, initial: true
aasm.state :active
aasm.state :completed
aasm.event :activate do |e|
e.transitions from: :pending, to: :active
end
aasm.event :complete do |e|
e.before { puts "completing..." }
e.after { puts "completed" }
e.transitions from: [:active, :pending], to: :completed
end
end
end
Related Skills
node-connect
345.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
104.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
345.4kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
345.4kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
