Fix hash calculation based on proto.Struct#1318
Conversation
0919511 to
c47da2f
Compare
Co-Authored-By: Nicolas Mahé <nicolas@mesg.com>
| // NOTE: structhash will allow to process all interface types. | ||
| // gogo/protobuf is not able to set tags for directly oneof interface. | ||
| // see: https://github.com/gogo/protobuf/issues/623 | ||
| { |
There was a problem hiding this comment.
Another problem, the following is returning {a:{b:1}}:
| { | |
| { | |
| struct { | |
| a interface{} | |
| }{ | |
| struct { | |
| b interface{} | |
| }{ | |
| b: 1, | |
| }, | |
| }, | |
| "{a:{}}", | |
| }, | |
| { |
There was a problem hiding this comment.
Solution, replace in structhash.go line 105 by:
- if to.name == "" && reflect.Zero(sf.Type).Kind() == reflect.Interface {
+ if to.name == "" && v.Field(i).Kind() == reflect.Interface && v.Field(i).Elem().Kind() == reflect.Struct {It will only continue if the field is defined as type interface and has as "real" type Struct.
There was a problem hiding this comment.
This is how it interface works. It's not a bug, it done design.
So let's break it down:
a struct is passed with a interface{] fileds which has no tag.
A struct is serialized and a field is serialized because it's an interface.
Then interface{} has struct inside. That struct is serialized because it's not a field of any struct, but rather the object (interface value). The struct contains b fields which is an interface so it's serialized and interface value contains an integer. So the final output should be {a:{b:1}}
There was a problem hiding this comment.
Test line 60 is wrong:
{
struct {
a int `hash:"omitempty"`
}{1},
"{}",
},
it should returns {a:1}
Solution:
Replace hash:"omitempty" by hash:"name:a,omitempty"
So any field without an explicit hash name is discarded?
It's not. Field |
close #1315