structs: fix nil pointer including, fixes #20
This commit is contained in:
parent
4018983491
commit
e1ea13a2d5
14
structs.go
14
structs.go
@ -92,7 +92,6 @@ func (s *Struct) Map() map[string]interface{} {
|
|||||||
// map[string]interface{} too
|
// map[string]interface{} too
|
||||||
finalVal = Map(val.Interface())
|
finalVal = Map(val.Interface())
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
finalVal = val.Interface()
|
finalVal = val.Interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,12 +399,17 @@ func HasZero(s interface{}) bool {
|
|||||||
// IsStruct returns true if the given variable is a struct or a pointer to
|
// IsStruct returns true if the given variable is a struct or a pointer to
|
||||||
// struct.
|
// struct.
|
||||||
func IsStruct(s interface{}) bool {
|
func IsStruct(s interface{}) bool {
|
||||||
t := reflect.TypeOf(s)
|
v := reflect.ValueOf(s)
|
||||||
if t.Kind() == reflect.Ptr {
|
if v.Kind() == reflect.Ptr {
|
||||||
t = t.Elem()
|
v = v.Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.Kind() == reflect.Struct
|
// uninitialized zero value of a struct
|
||||||
|
if v.Kind() == reflect.Invalid {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return v.Kind() == reflect.Struct
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name returns the structs's type name within its package. It returns an
|
// Name returns the structs's type name within its package. It returns an
|
||||||
|
|||||||
@ -773,3 +773,52 @@ func TestName(t *testing.T) {
|
|||||||
|
|
||||||
Name([]string{})
|
Name([]string{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNestedNilPointer(t *testing.T) {
|
||||||
|
type Collar struct {
|
||||||
|
Engraving string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Dog struct {
|
||||||
|
Name string
|
||||||
|
Collar *Collar
|
||||||
|
}
|
||||||
|
|
||||||
|
type Person struct {
|
||||||
|
Name string
|
||||||
|
Dog *Dog
|
||||||
|
}
|
||||||
|
|
||||||
|
person := &Person{
|
||||||
|
Name: "John",
|
||||||
|
}
|
||||||
|
|
||||||
|
personWithDog := &Person{
|
||||||
|
Name: "Ron",
|
||||||
|
Dog: &Dog{
|
||||||
|
Name: "Rover",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
personWithDogWithCollar := &Person{
|
||||||
|
Name: "Kon",
|
||||||
|
Dog: &Dog{
|
||||||
|
Name: "Ruffles",
|
||||||
|
Collar: &Collar{
|
||||||
|
Engraving: "If lost, call Kon",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
err := recover()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("err %+v\n", err)
|
||||||
|
t.Error("Internal nil pointer should not panic")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
_ = Map(person) // Panics
|
||||||
|
_ = Map(personWithDog) // Panics
|
||||||
|
_ = Map(personWithDogWithCollar) // Doesn't panic
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user