Skip to content

Commit

Permalink
add readme, changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
negasus committed Nov 8, 2024
1 parent 49450b3 commit ab5a0b4
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 0 deletions.
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changelog

## v0.1.0 (2024-11-08)

- initial release
11 changes: 11 additions & 0 deletions fsm.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@ import (
"sync"
)

// StateID is a type for state identifier
type StateID string

// Callback is a function that will be called on state transition
type Callback func(f *FSM, args ...any)

// FSM is a finite state machine
type FSM struct {
initialStateID StateID
callbacks map[StateID]Callback
userStatesMu sync.RWMutex
userStates map[int64]StateID
}

// New creates a new FSM
func New(initialStateName StateID, callbacks map[StateID]Callback) *FSM {
s := &FSM{
initialStateID: initialStateName,
Expand All @@ -30,16 +34,19 @@ func New(initialStateName StateID, callbacks map[StateID]Callback) *FSM {
return s
}

// AddCallback adds a callback for a state
func (f *FSM) AddCallback(stateID StateID, callback Callback) {
f.callbacks[stateID] = callback
}

// AddCallbacks adds callbacks for states
func (f *FSM) AddCallbacks(cb map[StateID]Callback) {
for stateID, callback := range cb {
f.callbacks[stateID] = callback
}
}

// Transition transitions the user to a new state
func (f *FSM) Transition(userID int64, stateID StateID, args ...any) {
f.userStatesMu.Lock()

Expand All @@ -58,6 +65,7 @@ func (f *FSM) Transition(userID int64, stateID StateID, args ...any) {
}
}

// Current returns the current state of the user
func (f *FSM) Current(userID int64) StateID {
f.userStatesMu.RLock()
defer f.userStatesMu.RUnlock()
Expand All @@ -71,12 +79,14 @@ func (f *FSM) Current(userID int64) StateID {
return userStateID
}

// Reset resets the state of the user to the initial state
func (f *FSM) Reset(userID int64) {
f.userStatesMu.Lock()
delete(f.userStates, userID)
f.userStatesMu.Unlock()
}

// MarshalJSON marshals the FSM to JSON
func (f *FSM) MarshalJSON() ([]byte, error) {
f.userStatesMu.RLock()
defer f.userStatesMu.RUnlock()
Expand All @@ -92,6 +102,7 @@ func (f *FSM) MarshalJSON() ([]byte, error) {
})
}

// UnmarshalJSON unmarshals the FSM from JSON
func (f *FSM) UnmarshalJSON(data []byte) error {
f.userStatesMu.Lock()
defer f.userStatesMu.Unlock()
Expand Down
9 changes: 9 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# FSM

This repo contains the code for a simple Finite State Machine (FSM) implemented for usage with `github.com/go-telegram/bot` library.

You can use this library for store the state of a conversation with a user in a Telegram bot.

## Usage

See an example of usage in the `example` folder.

0 comments on commit ab5a0b4

Please sign in to comment.