All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m9s
Test / Hakurei (push) Successful in 3m8s
Test / Hpkg (push) Successful in 4m2s
Test / Sandbox (race detector) (push) Successful in 4m7s
Test / Hakurei (race detector) (push) Successful in 4m55s
Test / Flake checks (push) Successful in 1m25s
This reduces collision with local variable names, and generally makes sense for the new store package, since it no longer specifies the state struct. Signed-off-by: Ophestra <cat@gensokyo.uk>
65 lines
1.0 KiB
Go
65 lines
1.0 KiB
Go
package store
|
|
|
|
import (
|
|
"errors"
|
|
"maps"
|
|
|
|
"hakurei.app/hst"
|
|
)
|
|
|
|
var (
|
|
ErrDuplicate = errors.New("store contains duplicates")
|
|
)
|
|
|
|
/*
|
|
Joiner is the interface that wraps the Join method.
|
|
|
|
The Join function uses Joiner if available.
|
|
*/
|
|
type Joiner interface {
|
|
Join() (map[hst.ID]*hst.State, error)
|
|
}
|
|
|
|
// Join returns joined state entries of all active identities.
|
|
func Join(s Store) (map[hst.ID]*hst.State, error) {
|
|
if j, ok := s.(Joiner); ok {
|
|
return j.Join()
|
|
}
|
|
|
|
var (
|
|
aids []int
|
|
entries = make(map[hst.ID]*hst.State)
|
|
|
|
el int
|
|
res map[hst.ID]*hst.State
|
|
loadErr error
|
|
)
|
|
|
|
if ln, err := s.List(); err != nil {
|
|
return nil, err
|
|
} else {
|
|
aids = ln
|
|
}
|
|
|
|
for _, aid := range aids {
|
|
if _, err := s.Do(aid, func(c Cursor) {
|
|
res, loadErr = c.Load()
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if loadErr != nil {
|
|
return nil, loadErr
|
|
}
|
|
|
|
// save expected length
|
|
el = len(entries) + len(res)
|
|
maps.Copy(entries, res)
|
|
if len(entries) != el {
|
|
return nil, ErrDuplicate
|
|
}
|
|
}
|
|
|
|
return entries, nil
|
|
}
|