-
Notifications
You must be signed in to change notification settings - Fork 198
Closed
Description
For a user defined struct as follows
//go:generate msgp
//msgp:tuple User
type User struct {
ID []byte `msgpack:"id,allownil"`
Name string `msgpack:"name"`
Email string `msgpack:"email"`
IsActive bool `msgpack:"is_active"`
}
The ID is tagged as allownil
i want to pack it like tuples, so i use msgp:tuple directive
after i execute go generate i get a MarshalMsg As Follows
// MarshalMsg implements msgp.Marshaler
func (z *User) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize())
// array header, size 4
if z.ID == nil { // allownil: if nil
o = msgp.AppendNil(o)
} else {
o = append(o, 0x94)
o = msgp.AppendBytes(o, z.ID)
}
o = msgp.AppendString(o, z.Name)
o = msgp.AppendString(o, z.Email)
o = msgp.AppendBool(o, z.IsActive)
return
}
Just as you can see, only when ID is not nil, the number of elements 0x94 is packed into the results.
But if ID is nil, then the number of elements is not packed, which is obviously wrong.
I think the problem lies in gen/marshal.go
func (m *marshalGen) tuple(s *Struct) {
data := make([]byte, 0, 5)
data = msgp.AppendArrayHeader(data, uint32(len(s.Fields)))
m.p.printf("\n// array header, size %d", len(s.Fields))
m.Fuse(data)
if len(s.Fields) == 0 {
m.fuseHook()
return
}
for i := range s.Fields {
if !m.p.ok() {
return
}
fieldElem := s.Fields[i].FieldElem
anField := s.Fields[i].HasTagPart("allownil") && fieldElem.AllowNil()
if anField {
m.p.printf("\nif %s { // allownil: if nil", fieldElem.IfZeroExpr())
m.p.printf("\no = msgp.AppendNil(o)")
m.p.printf("\n} else {")
}
m.ctx.PushString(s.Fields[i].FieldName)
SetIsAllowNil(fieldElem, anField)
next(m, fieldElem)
m.ctx.Pop()
if anField {
m.p.printf("\n}") // close if statement
}
}
}
if i change code snippet
m.Fuse(data)
if len(s.Fields) == 0 {
m.fuseHook()
return
}
to
m.Fuse(data)
m.fuseHook()
if len(s.Fields) == 0 {
return
}
it works! The generated MarshalMsg is as follows
// MarshalMsg implements msgp.Marshaler
func (z *User) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize())
// array header, size 4
o = append(o, 0x94)
if z.ID == nil { // allownil: if nil
o = msgp.AppendNil(o)
} else {
o = msgp.AppendBytes(o, z.ID)
}
o = msgp.AppendString(o, z.Name)
o = msgp.AppendString(o, z.Email)
o = msgp.AppendBool(o, z.IsActive)
return
}
Metadata
Metadata
Assignees
Labels
No labels