aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/state/join.go
blob: 2b4011fe5c8badcfff0bd27af52415eed8eab48d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package state

import (
	"errors"
	"maps"
)

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() (Entries, error) }

// Join returns joined state entries of all active aids.
func Join(s Store) (Entries, error) {
	if j, ok := s.(Joiner); ok {
		return j.Join()
	}

	var (
		aids    []int
		entries = make(Entries)

		el      int
		res     Entries
		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
}