structure: fix mixed up indexes, fixes #8. Thanks @yrashk for reporting
This commit is contained in:
parent
241e969210
commit
e34cf80acb
33
structure.go
33
structure.go
@ -24,9 +24,9 @@ func Map(s interface{}) map[string]interface{} {
|
|||||||
|
|
||||||
v, fields := strctInfo(s)
|
v, fields := strctInfo(s)
|
||||||
|
|
||||||
for i, field := range fields {
|
for _, field := range fields {
|
||||||
name := field.Name
|
name := field.Name
|
||||||
val := v.Field(i)
|
val := v.FieldByName(name)
|
||||||
|
|
||||||
var finalVal interface{}
|
var finalVal interface{}
|
||||||
|
|
||||||
@ -63,8 +63,8 @@ func Values(s interface{}) []interface{} {
|
|||||||
v, fields := strctInfo(s)
|
v, fields := strctInfo(s)
|
||||||
|
|
||||||
t := make([]interface{}, 0)
|
t := make([]interface{}, 0)
|
||||||
for i := range fields {
|
for _, field := range fields {
|
||||||
val := v.Field(i)
|
val := v.FieldByName(field.Name)
|
||||||
if IsStruct(val.Interface()) {
|
if IsStruct(val.Interface()) {
|
||||||
// look out for embedded structs, and convert them to a
|
// look out for embedded structs, and convert them to a
|
||||||
// []interface{} to be added to the final values slice
|
// []interface{} to be added to the final values slice
|
||||||
@ -92,8 +92,9 @@ func Values(s interface{}) []interface{} {
|
|||||||
func IsZero(s interface{}) bool {
|
func IsZero(s interface{}) bool {
|
||||||
v, fields := strctInfo(s)
|
v, fields := strctInfo(s)
|
||||||
|
|
||||||
for i := range fields {
|
for _, field := range fields {
|
||||||
val := v.Field(i)
|
val := v.FieldByName(field.Name)
|
||||||
|
|
||||||
if IsStruct(val.Interface()) {
|
if IsStruct(val.Interface()) {
|
||||||
ok := IsZero(val.Interface())
|
ok := IsZero(val.Interface())
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -104,10 +105,10 @@ func IsZero(s interface{}) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// zero value of the given field, such as "" for string, 0 for int
|
// zero value of the given field, such as "" for string, 0 for int
|
||||||
zero := reflect.Zero(v.Field(i).Type()).Interface()
|
zero := reflect.Zero(val.Type()).Interface()
|
||||||
|
|
||||||
// current value of the given field
|
// current value of the given field
|
||||||
current := v.Field(i).Interface()
|
current := val.Interface()
|
||||||
|
|
||||||
if !reflect.DeepEqual(current, zero) {
|
if !reflect.DeepEqual(current, zero) {
|
||||||
return false
|
return false
|
||||||
@ -129,8 +130,8 @@ func IsZero(s interface{}) bool {
|
|||||||
func HasZero(s interface{}) bool {
|
func HasZero(s interface{}) bool {
|
||||||
v, fields := strctInfo(s)
|
v, fields := strctInfo(s)
|
||||||
|
|
||||||
for i := range fields {
|
for _, field := range fields {
|
||||||
val := v.Field(i)
|
val := v.FieldByName(field.Name)
|
||||||
if IsStruct(val.Interface()) {
|
if IsStruct(val.Interface()) {
|
||||||
ok := HasZero(val.Interface())
|
ok := HasZero(val.Interface())
|
||||||
if ok {
|
if ok {
|
||||||
@ -141,10 +142,10 @@ func HasZero(s interface{}) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// zero value of the given field, such as "" for string, 0 for int
|
// zero value of the given field, such as "" for string, 0 for int
|
||||||
zero := reflect.Zero(v.Field(i).Type()).Interface()
|
zero := reflect.Zero(val.Type()).Interface()
|
||||||
|
|
||||||
// current value of the given field
|
// current value of the given field
|
||||||
current := v.Field(i).Interface()
|
current := val.Interface()
|
||||||
|
|
||||||
if reflect.DeepEqual(current, zero) {
|
if reflect.DeepEqual(current, zero) {
|
||||||
return true
|
return true
|
||||||
@ -166,8 +167,8 @@ func Fields(s interface{}) []string {
|
|||||||
v, fields := strctInfo(s)
|
v, fields := strctInfo(s)
|
||||||
|
|
||||||
keys := make([]string, 0)
|
keys := make([]string, 0)
|
||||||
for i, field := range fields {
|
for _, field := range fields {
|
||||||
val := v.Field(i)
|
val := v.FieldByName(field.Name)
|
||||||
if IsStruct(val.Interface()) {
|
if IsStruct(val.Interface()) {
|
||||||
// look out for embedded structs, and convert them to a
|
// look out for embedded structs, and convert them to a
|
||||||
// []string to be added to the final values slice
|
// []string to be added to the final values slice
|
||||||
@ -214,8 +215,8 @@ func Name(s interface{}) string {
|
|||||||
func Has(s interface{}, fieldName string) bool {
|
func Has(s interface{}, fieldName string) bool {
|
||||||
v, fields := strctInfo(s)
|
v, fields := strctInfo(s)
|
||||||
|
|
||||||
for i, field := range fields {
|
for _, field := range fields {
|
||||||
val := v.Field(i)
|
val := v.FieldByName(field.Name)
|
||||||
|
|
||||||
if IsStruct(val.Interface()) {
|
if IsStruct(val.Interface()) {
|
||||||
if ok := Has(val.Interface(), fieldName); ok {
|
if ok := Has(val.Interface(), fieldName); ok {
|
||||||
|
|||||||
@ -19,6 +19,27 @@ func TestMapNonStruct(t *testing.T) {
|
|||||||
_ = Map(foo)
|
_ = Map(foo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStructIndexes(t *testing.T) {
|
||||||
|
type C struct {
|
||||||
|
something int
|
||||||
|
Props map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
err := recover()
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Using mixed indexes should not panic")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// They should not panic
|
||||||
|
_ = Map(&C{})
|
||||||
|
_ = Fields(&C{})
|
||||||
|
_ = Values(&C{})
|
||||||
|
_ = IsZero(&C{})
|
||||||
|
_ = HasZero(&C{})
|
||||||
|
}
|
||||||
|
|
||||||
func TestMap(t *testing.T) {
|
func TestMap(t *testing.T) {
|
||||||
var T = struct {
|
var T = struct {
|
||||||
A string
|
A string
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user