feat: added convenient state groups api

This commit is contained in:
abelith committed 2026-10-09 11:06:30 +03:00
1 parent 7bb08f60f3
commit 7a4e34528f
5 files changed
+63 -11

No files matched your search

+1 -1
View File
@@ -2,7 +2,7 @@ package context
import (
"context"
"github.com/abelith/gomax/v1/state"
"github.com/abelith/gomax/v1/fsm/state"
maxbot "github.com/max-messenger/max-bot-api-client-go/v2"
"github.com/max-messenger/max-bot-api-client-go/v2/model"
"time"
+2 -2
View File
@@ -4,9 +4,9 @@ import (
"context"
"errors"
mcontext "github.com/abelith/gomax/v1/context"
"github.com/abelith/gomax/v1/fsm/memory"
"github.com/abelith/gomax/v1/fsm/state"
"github.com/abelith/gomax/v1/isolation"
"github.com/abelith/gomax/v1/state"
"github.com/abelith/gomax/v1/state/memory"
"github.com/google/uuid"
maxbot "github.com/max-messenger/max-bot-api-client-go/v2"
"github.com/max-messenger/max-bot-api-client-go/v2/model"
+1 -1
View File
@@ -2,7 +2,7 @@ package filters
import (
mcontext "github.com/abelith/gomax/v1/context"
"github.com/abelith/gomax/v1/state"
"github.com/abelith/gomax/v1/fsm/state"
"github.com/max-messenger/max-bot-api-client-go/v2/model"
"regexp"
"strings"
@@ -2,8 +2,8 @@ package memory
import (
"context"
"github.com/abelith/gomax/v1/fsm/state"
"github.com/abelith/gomax/v1/isolation"
"github.com/abelith/gomax/v1/state"
"github.com/google/uuid"
"sync"
"time"
+58 -6
View File
@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"github.com/abelith/gomax/v1/isolation"
"strings"
)
var (
@@ -11,7 +12,15 @@ var (
ErrKeyNotFound = fmt.Errorf("state: key not found")
)
type State string
type State struct {
group string
name string
}
type Group struct {
name string
states map[string]*State
}
type Codec interface {
Marshal(v any) ([]byte, error)
@@ -30,7 +39,7 @@ func (JSONCodec) Unmarshal(d []byte, v any) error {
type Snapshot struct {
Scope isolation.Scope `json:"id"`
State State `json:"state"`
State string `json:"state"`
Data map[string][]byte `json:"data"`
}
@@ -44,6 +53,49 @@ type Context struct {
type Option func(*Context)
func NewStateGroup(name string) *Group {
return &Group{
name: name,
states: make(map[string]*State),
}
}
func (g *Group) State(name string) State {
state := g.states[name]
if state != nil {
return *state
}
if state = g.states[name]; state != nil {
return *state
}
state = &State{
group: g.name,
name: name,
}
g.states[name] = state
return *state
}
func (s *State) String() string {
return fmt.Sprintf("%s:%s", s.group, s.name)
}
func fromString(s string) State {
pieces := strings.Split(s, ":")
if len(pieces) < 2 {
return State{}
}
return State{
group: pieces[0],
name: pieces[1],
}
}
func WithCodec(c Codec) Option { return func(sc *Context) { sc.codec = c } }
func New(scope isolation.Scope, opts ...Option) *Context {
@@ -60,7 +112,7 @@ func New(scope isolation.Scope, opts ...Option) *Context {
func Restore(s Snapshot, opts ...Option) *Context {
sc := New(s.Scope, opts...)
sc.state = s.State
sc.state = fromString(s.State)
for k, v := range s.Data {
sc.data[k] = v
}
@@ -72,7 +124,7 @@ func (sc *Context) Snapshot() Snapshot {
for k, v := range sc.data {
data[k] = v
}
return Snapshot{Scope: sc.scope, State: sc.state, Data: data}
return Snapshot{Scope: sc.scope, State: sc.state.String(), Data: data}
}
func (sc *Context) Set(state State) {
@@ -82,13 +134,13 @@ func (sc *Context) Set(state State) {
func (sc *Context) State() State { return sc.state }
func (sc *Context) Clear() {
sc.state = ""
sc.state = State{}
sc.clear = true
sc.data = make(map[string][]byte)
}
func (sc *Context) IsEmpty() bool {
return sc.state == "" && sc.clear
return sc.state == State{} && sc.clear
}
func (sc *Context) Store(key string, val any) error {