package meshtest import ( "encoding/json" "sort" "sync" stdio "git.novox.be/novox/mesh-sdk/go" ) // State is a module's state as a fixture, the shape a gate's Store takes: Fail makes every read and write fail, as a bus // refusing them; Vals are its values by key. type State struct { mu sync.Mutex Vals map[string]json.RawMessage revs map[string]uint64 n uint64 Fail error } // NewState is an empty State. func NewState() *State { return &State{Vals: map[string]json.RawMessage{}, revs: map[string]uint64{}} } func (m *State) Get(k string) (*stdio.StateEntry, error) { m.mu.Lock() defer m.mu.Unlock() if m.Fail != nil { return nil, m.Fail } v, ok := m.Vals[k] if !ok { return nil, nil } return &stdio.StateEntry{Key: k, Value: v, Revision: m.revs[k]}, nil } func (m *State) Create(k string, v any) (uint64, error) { m.mu.Lock() defer m.mu.Unlock() if m.Fail != nil { return 0, m.Fail } if _, ok := m.Vals[k]; ok { return 0, stdio.ErrChanged } return m.put(k, v) } func (m *State) Update(k string, v any, rev uint64) (uint64, error) { m.mu.Lock() defer m.mu.Unlock() if m.Fail != nil { return 0, m.Fail } if rev == 0 || m.revs[k] != rev { return 0, stdio.ErrChanged } return m.put(k, v) } func (m *State) Put(k string, v any) (uint64, error) { m.mu.Lock() defer m.mu.Unlock() if m.Fail != nil { return 0, m.Fail } return m.put(k, v) } func (m *State) Keys() ([]string, error) { m.mu.Lock() defer m.mu.Unlock() if m.Fail != nil { return nil, m.Fail } var out []string for k := range m.Vals { out = append(out, k) } sort.Strings(out) return out, nil } func (m *State) put(k string, v any) (uint64, error) { raw, ok := v.(json.RawMessage) if !ok { raw, _ = json.Marshal(v) } m.n++ m.Vals[k], m.revs[k] = raw, m.n return m.n, nil }