avoid double Prepare for Container

This commit is contained in:
Josh Deprez 2021-10-05 11:03:29 +11:00
parent e2b4786484
commit 065ccf19e5
2 changed files with 18 additions and 27 deletions

View file

@ -23,7 +23,6 @@ import (
) )
var _ interface { var _ interface {
Prepper
Scanner Scanner
gob.GobDecoder gob.GobDecoder
gob.GobEncoder gob.GobEncoder
@ -44,16 +43,27 @@ type Container struct {
// MakeContainer puts the items into a new Container. // MakeContainer puts the items into a new Container.
func MakeContainer(items ...interface{}) *Container { func MakeContainer(items ...interface{}) *Container {
c := &Container{items: items} c := &Container{items: items}
c.Prepare(nil) c.rebuildReverse()
return c return c
} }
func (c *Container) rebuildReverse() {
if c == nil {
return
}
c.reverse = make(map[interface{}]int, len(c.items))
for i, x := range c.items {
c.reverse[x] = i
}
}
// GobDecode decodes a byte slice as though it were a slice of items. // GobDecode decodes a byte slice as though it were a slice of items.
func (c *Container) GobDecode(in []byte) error { func (c *Container) GobDecode(in []byte) error {
if err := gob.NewDecoder(bytes.NewReader(in)).Decode(&c.items); err != nil { if err := gob.NewDecoder(bytes.NewReader(in)).Decode(&c.items); err != nil {
return err return err
} }
return c.Prepare(nil) c.rebuildReverse()
return nil
} }
// GobEncode encodes c as the slice of items. // GobEncode encodes c as the slice of items.
@ -70,19 +80,6 @@ func (c *Container) GobEncode() ([]byte, error) {
return buf.Bytes(), nil return buf.Bytes(), nil
} }
// Prepare ensures the helper data structures are present and valid.
// Prepare is safe to call on a nil *Container.
func (c *Container) Prepare(*Game) error {
if c == nil {
return nil
}
c.reverse = make(map[interface{}]int, len(c.items))
for i, x := range c.items {
c.reverse[x] = i
}
return nil
}
// Scan visits every non-nil component in the container. // Scan visits every non-nil component in the container.
// Scan is safe to call on a nil *Container. // Scan is safe to call on a nil *Container.
func (c *Container) Scan(visit VisitFunc) error { func (c *Container) Scan(visit VisitFunc) error {
@ -90,10 +87,11 @@ func (c *Container) Scan(visit VisitFunc) error {
return nil return nil
} }
for _, x := range c.items { for _, x := range c.items {
if x != nil { if x == nil {
if err := visit(x); err != nil { continue
return err }
} if err := visit(x); err != nil {
return err
} }
} }
return nil return nil

View file

@ -22,13 +22,6 @@ import (
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
) )
func TestContainerLiteral(t *testing.T) {
c := &Container{}
if err := c.Prepare(nil); err != nil {
t.Errorf("c.Prepare() = %v, want nil", err)
}
}
func TestMakeContainer(t *testing.T) { func TestMakeContainer(t *testing.T) {
c := MakeContainer(69, 420) c := MakeContainer(69, 420)
if want := []interface{}{69, 420}; !cmp.Equal(c.items, want) { if want := []interface{}{69, 420}; !cmp.Equal(c.items, want) {