Skip to content

Commit

Permalink
Add map[string]struct{} support
Browse files Browse the repository at this point in the history
Empty structs used as map values would generate invalid code.

Fixes #298
  • Loading branch information
klauspost committed Feb 10, 2024
1 parent cabc832 commit 428170d
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 24 deletions.
45 changes: 26 additions & 19 deletions _generated/def.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,31 @@ type TestType struct {
ValueA string `msg:"value_a"`
ValueB []byte `msg:"value_b"`
} `msg:"object"`
Child *TestType `msg:"child"`
Time time.Time `msg:"time"`
Any interface{} `msg:"any"`
Appended msgp.Raw `msg:"appended"`
Num msgp.Number `msg:"num"`
Byte byte
Rune rune
RunePtr *rune
RunePtrPtr **rune
RuneSlice []rune
Slice1 []string
Slice2 []string
SlicePtr *[]string
Child *TestType `msg:"child"`
Time time.Time `msg:"time"`
Any interface{} `msg:"any"`
Appended msgp.Raw `msg:"appended"`
Num msgp.Number `msg:"num"`
Byte byte
Rune rune
RunePtr *rune
RunePtrPtr **rune
RuneSlice []rune
Slice1 []string
Slice2 []string
SlicePtr *[]string
MapStringEmpty map[string]struct{}
MapStringEmpty2 map[string]EmptyStruct
}

//msgp:tuple Object
type Object struct {
ObjectNo string `msg:"objno"`
Slice1 []string `msg:"slice1"`
Slice2 []string `msg:"slice2"`
MapMap map[string]map[string]string
ObjectNo string `msg:"objno"`
Slice1 []string `msg:"slice1"`
Slice2 []string `msg:"slice2"`
MapMap map[string]map[string]string
MapStringEmpty map[string]struct{}
MapStringEmpty2 map[string]EmptyStruct
}

//msgp:tuple TestBench
Expand Down Expand Up @@ -266,8 +270,11 @@ type NonMsgStructTags struct {
B string `json:"b"`
C []string `json:"c"`
VeryNested []struct {
A []string `json:"a"`
B []string `msg:"bbbb" xml:"-"`
A []string `json:"a"`
B []string `msg:"bbbb" xml:"-"`
C map[string]struct{} `msg:"cccc"`
}
}
}

type EmptyStruct struct{}
21 changes: 16 additions & 5 deletions _generated/gen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ func (a *TestType) Equal(b *TestType) bool {
if !bytes.Equal(aa, ab) {
return false
}
if len(a.MapStringEmpty) == 0 && len(b.MapStringEmpty) == 0 {
a.MapStringEmpty = nil
b.MapStringEmpty = nil
}
if len(a.MapStringEmpty2) == 0 && len(b.MapStringEmpty2) == 0 {
a.MapStringEmpty2 = nil
b.MapStringEmpty2 = nil
}

a.Time, b.Time = time.Time{}, time.Time{}
aa, ab = nil, nil
ok := reflect.DeepEqual(a, b)
Expand Down Expand Up @@ -97,9 +106,11 @@ func Test1EncodeDecode(t *testing.T) {
ValueA: "here's the first inner value",
ValueB: []byte("here's the second inner value"),
},
Child: nil,
Time: time.Now(),
Appended: msgp.Raw([]byte{}), // 'nil'
Child: nil,
Time: time.Now(),
Appended: msgp.Raw([]byte{}), // 'nil'
MapStringEmpty: map[string]struct{}{"Key": {}, "Key2": {}},
MapStringEmpty2: map[string]EmptyStruct{"Key3": {}, "Key4": {}},
}

var buf bytes.Buffer
Expand All @@ -117,8 +128,8 @@ func Test1EncodeDecode(t *testing.T) {
}

if !tt.Equal(tnew) {
t.Logf("in: %v", tt)
t.Logf("out: %v", tnew)
t.Logf("in: %#v", tt)
t.Logf("out: %#v", tnew)
t.Fatal("objects not equal")
}

Expand Down
1 change: 1 addition & 0 deletions gen/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ func (d *decodeGen) gMap(m *Map) {

// for element in map, read string/value
// pair and assign
d.needsField()
d.p.printf("\nfor %s > 0 {\n%s--", sz, sz)
d.p.declare(m.Keyidx, "string")
d.p.declare(m.Validx, m.Value.TypeName())
Expand Down
1 change: 1 addition & 0 deletions gen/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ func (e *encodeGen) structmap(s *Struct) {
e.p.printf("\n// map header, size %d", nfields)
e.Fuse(data)
if len(s.Fields) == 0 {
e.p.printf("\n_ = %s", s.vname)
e.fuseHook()
}

Expand Down
1 change: 1 addition & 0 deletions gen/marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ func (m *marshalGen) mapstruct(s *Struct) {
m.p.printf("\n// map header, size %d", len(s.Fields))
m.Fuse(data)
if len(s.Fields) == 0 {
m.p.printf("\n_ = %s", s.vname)
m.fuseHook()
}

Expand Down
4 changes: 4 additions & 0 deletions gen/unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ func (u *unmarshalGen) gMap(m *Map) {
// allocate or clear map
u.p.resizeMap(sz, m)

// We likely need a field.
// Add now to not be inside for scope.
u.needsField()

// loop and get key,value
u.p.printf("\nfor %s > 0 {", sz)
u.p.printf("\nvar %s string; var %s %s; %s--", m.Keyidx, m.Validx, m.Value.TypeName(), sz)
Expand Down

0 comments on commit 428170d

Please sign in to comment.