structure: Add Has() method, fix IsZero()
This commit is contained in:
parent
e68f708c4c
commit
31b952e111
@ -45,8 +45,12 @@ f := structure.Fields(s)
|
|||||||
// => "Server"
|
// => "Server"
|
||||||
n := structure.Name(s)
|
n := structure.Name(s)
|
||||||
|
|
||||||
|
// Check if field name exists
|
||||||
|
// => true
|
||||||
|
n := structure.Has(s, "Enabled")
|
||||||
|
|
||||||
// Check if the fields of a struct is initialized or not.
|
// Check if the fields of a struct is initialized or not.
|
||||||
if structure.IsZero(s) {
|
if !structure.IsZero(s) {
|
||||||
fmt.Println("s is initialized")
|
fmt.Println("s is initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
32
structure.go
32
structure.go
@ -80,7 +80,7 @@ func Values(s interface{}) []interface{} {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsZero returns true if all fields in a struct are initialized (non zero
|
// IsZero returns true if any field in a struct is not initialized (zero
|
||||||
// value). A struct tag with the content of "-" ignores the checking of that
|
// value). A struct tag with the content of "-" ignores the checking of that
|
||||||
// particular field. Example:
|
// particular field. Example:
|
||||||
//
|
//
|
||||||
@ -96,8 +96,8 @@ func IsZero(s interface{}) bool {
|
|||||||
val := v.Field(i)
|
val := v.Field(i)
|
||||||
if IsStruct(val.Interface()) {
|
if IsStruct(val.Interface()) {
|
||||||
ok := IsZero(val.Interface())
|
ok := IsZero(val.Interface())
|
||||||
if !ok {
|
if ok {
|
||||||
return false
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
@ -110,11 +110,11 @@ func IsZero(s interface{}) bool {
|
|||||||
current := v.Field(i).Interface()
|
current := v.Field(i).Interface()
|
||||||
|
|
||||||
if reflect.DeepEqual(current, zero) {
|
if reflect.DeepEqual(current, zero) {
|
||||||
return false
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fields returns a slice of field names. A struct tag with the content of "-"
|
// Fields returns a slice of field names. A struct tag with the content of "-"
|
||||||
@ -172,6 +172,28 @@ func Name(s interface{}) string {
|
|||||||
return t.Name()
|
return t.Name()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Has returns true if the given field name exists for the struct s. It panic's
|
||||||
|
// if s's kind is not struct.
|
||||||
|
func Has(s interface{}, fieldName string) bool {
|
||||||
|
v, fields := strctInfo(s)
|
||||||
|
|
||||||
|
for i, field := range fields {
|
||||||
|
val := v.Field(i)
|
||||||
|
|
||||||
|
if IsStruct(val.Interface()) {
|
||||||
|
if ok := Has(val.Interface(), fieldName); ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if field.Name == fieldName {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// strctInfo returns the struct value and the exported struct fields for a
|
// strctInfo returns the struct value and the exported struct fields for a
|
||||||
// given s struct. This is a convenient helper method to avoid duplicate code
|
// given s struct. This is a convenient helper method to avoid duplicate code
|
||||||
// in some of the functions.
|
// in some of the functions.
|
||||||
|
|||||||
@ -110,7 +110,7 @@ func ExampleIsZero() {
|
|||||||
a := &Access{
|
a := &Access{
|
||||||
LastAccessed: time.Now(),
|
LastAccessed: time.Now(),
|
||||||
}
|
}
|
||||||
validA := IsZero(a)
|
isZeroA := IsZero(a)
|
||||||
|
|
||||||
// Name and Number is initialized.
|
// Name and Number is initialized.
|
||||||
b := &Access{
|
b := &Access{
|
||||||
@ -118,11 +118,31 @@ func ExampleIsZero() {
|
|||||||
LastAccessed: time.Now(),
|
LastAccessed: time.Now(),
|
||||||
Number: 12345,
|
Number: 12345,
|
||||||
}
|
}
|
||||||
validB := IsZero(b)
|
isZeroB := IsZero(b)
|
||||||
|
|
||||||
fmt.Printf("%#v\n", validA)
|
fmt.Printf("%#v\n", isZeroA)
|
||||||
fmt.Printf("%#v\n", validB)
|
fmt.Printf("%#v\n", isZeroB)
|
||||||
// Output:
|
// Output:
|
||||||
// false
|
|
||||||
// true
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleHas() {
|
||||||
|
type Access struct {
|
||||||
|
Name string
|
||||||
|
LastAccessed time.Time
|
||||||
|
Number int
|
||||||
|
}
|
||||||
|
|
||||||
|
s := &Access{
|
||||||
|
Name: "Fatih",
|
||||||
|
LastAccessed: time.Now(),
|
||||||
|
Number: 1234567,
|
||||||
|
}
|
||||||
|
|
||||||
|
found := Has(s, "LastAccessed")
|
||||||
|
|
||||||
|
fmt.Printf("Has: %+v\n", found)
|
||||||
|
// Output:
|
||||||
|
// Has: true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -357,8 +357,8 @@ func TestIsZero(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ok := IsZero(T)
|
ok := IsZero(T)
|
||||||
if ok {
|
if !ok {
|
||||||
t.Error("IsZero should return false because D is not initialized")
|
t.Error("IsZero should return true because A and B are initialized.")
|
||||||
}
|
}
|
||||||
|
|
||||||
var X = struct {
|
var X = struct {
|
||||||
@ -369,8 +369,21 @@ func TestIsZero(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ok = IsZero(X)
|
ok = IsZero(X)
|
||||||
|
if !ok {
|
||||||
|
t.Error("IsZero should return true because A is initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
var Y = struct {
|
||||||
|
A string
|
||||||
|
B int
|
||||||
|
}{
|
||||||
|
A: "a-value",
|
||||||
|
B: 123,
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = IsZero(Y)
|
||||||
if ok {
|
if ok {
|
||||||
t.Error("IsZero should return false because F is not initialized")
|
t.Error("IsZero should return false because A and B is initialized")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,8 +401,8 @@ func TestIsZero_Nested(t *testing.T) {
|
|||||||
b := &B{A: a, C: 123}
|
b := &B{A: a, C: 123}
|
||||||
|
|
||||||
ok := IsZero(b)
|
ok := IsZero(b)
|
||||||
if ok {
|
if !ok {
|
||||||
t.Error("IsZero should return false because D is not initialized")
|
t.Error("IsZero should return true because D is not initialized")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,11 +421,38 @@ func TestIsZero_Anonymous(t *testing.T) {
|
|||||||
b.A = a
|
b.A = a
|
||||||
|
|
||||||
ok := IsZero(b)
|
ok := IsZero(b)
|
||||||
if ok {
|
if !ok {
|
||||||
t.Error("IsZero should return false because D is not initialized")
|
t.Error("IsZero should return false because D is not initialized")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHas(t *testing.T) {
|
||||||
|
type A struct {
|
||||||
|
Name string
|
||||||
|
D string
|
||||||
|
}
|
||||||
|
a := A{Name: "example"}
|
||||||
|
|
||||||
|
type B struct {
|
||||||
|
A
|
||||||
|
C int
|
||||||
|
}
|
||||||
|
b := &B{C: 123}
|
||||||
|
b.A = a
|
||||||
|
|
||||||
|
if !Has(b, "Name") {
|
||||||
|
t.Error("Has should return true for Name, but it's false")
|
||||||
|
}
|
||||||
|
|
||||||
|
if Has(b, "NotAvailable") {
|
||||||
|
t.Error("Has should return false for NotAvailable, but it's true")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !Has(b, "C") {
|
||||||
|
t.Error("Has should return true for C, but it's false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestName(t *testing.T) {
|
func TestName(t *testing.T) {
|
||||||
type Foo struct {
|
type Foo struct {
|
||||||
A string
|
A string
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user