structure: add Fields() function, closes #4

This commit is contained in:
Fatih Arslan 2014-07-27 23:52:52 +03:00
parent afdeeccc8b
commit 2d4d14a6c8
4 changed files with 79 additions and 5 deletions

View File

@ -28,7 +28,7 @@ s := &Server{
#### ToMap()
Convert to a `map[string]interface{}`
Convert a struct to a `map[string]interface{}`
```go
m := structure.ToMap(s)
@ -39,8 +39,8 @@ fmt.Printf("%#v", m)
#### ToSlice()
Convert to a `[]interface{}`. Slice values are **sorted** by default according
to the field names.
Convert the values of a struct to a `[]interface{}`. Slice values are
**sorted** by default according to the field names.
```go
m := structure.ToSlice(s)
@ -49,6 +49,18 @@ m := structure.ToSlice(s)
fmt.Printf("%#v", m)
```
#### Fields()
Convert the fields of a struct to a `[]string`. Slice values are **sorted** by
default according to the field names.
```go
m := structure.Fields(s)
// prints: []string{"Enabled", "ID", "Name"}
fmt.Printf("%#v", m)
```
#### IsStruct()
Check if it's a struct or a pointer to struct

View File

@ -74,7 +74,8 @@ func ToSlice(s interface{}) []interface{} {
}
// Fields returns a sorted slice of field names.
// Fields returns a sorted slice of field names. Note that only exported
// fields of a struct can be accessed, non exported fields will be neglected.
func Fields(s interface{}) []string {
m := ToMap(s)

View File

@ -1,6 +1,9 @@
package structure
import "fmt"
import (
"fmt"
"time"
)
func ExampleToMap() {
type Server struct {
@ -73,3 +76,24 @@ func ExampleToSlice() {
// Output:
// []interface {}{false, 135790, "Fatih"}
}
func ExampleFields() {
type Access struct {
Name string
LastAccessed time.Time
Number int
}
s := &Access{
Name: "Fatih",
LastAccessed: time.Now(),
Number: 1234567,
}
m := Fields(s)
// note that the output is sorted according to the field names
fmt.Printf("%#v\n", m)
// Output:
// []string{"LastAccessed", "Name", "Number"}
}

View File

@ -115,6 +115,10 @@ func TestToSlice(t *testing.T) {
s := ToSlice(T)
if typ := reflect.TypeOf(s).Kind(); typ != reflect.Slice {
t.Errorf("ToSlice should return a slice type, got: %v", typ)
}
inSlice := func(val interface{}) bool {
for _, v := range s {
if reflect.DeepEqual(v, val) {
@ -130,3 +134,36 @@ func TestToSlice(t *testing.T) {
}
}
}
func TestFields(t *testing.T) {
var T = struct {
A string
B int
C bool
}{
A: "a-value",
B: 2,
C: true,
}
s := Fields(T)
if len(s) != 3 {
t.Errorf("Fields should return a slice of len 3, got: %d", len(s))
}
inSlice := func(val string) bool {
for _, v := range s {
if reflect.DeepEqual(v, val) {
return true
}
}
return false
}
for _, val := range []string{"A", "B", "C"} {
if !inSlice(val) {
t.Errorf("Fields should have the value %v", val)
}
}
}