From 0aaea945f58a2add8c5191305bc6922be701b395 Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Wed, 30 Jul 2014 17:43:09 +0300 Subject: [PATCH] structure: add Name() function --- README.md | 4 ++++ structure.go | 45 +++++++++++++++++++++++++++++++++------------ structure_test.go | 13 +++++++++++++ 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 30301b4..a4fb33e 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,10 @@ v := structure.Values(s) // => ["Enabled", "ID", "Name"] f := structure.Fields(s) +// Return the struct name +// => "Server" +n := structure.Name(s) + // Check if the fields of a struct is initialized or not. if structure.IsValid(s) { fmt.Println("s is initialized") diff --git a/structure.go b/structure.go index 972b390..1c3298f 100644 --- a/structure.go +++ b/structure.go @@ -94,7 +94,7 @@ func IsValid(s interface{}) bool { // Field bool `structure:"-"` // // Note that only exported fields of a struct can be accessed, non exported -// fields will be neglected. +// fields will be neglected. It panics if s's kind is not struct. func Fields(s interface{}) []string { _, fields := strctInfo(s) @@ -117,21 +117,27 @@ func IsStruct(s interface{}) bool { return t.Kind() == reflect.Struct } +// Name returns the structs's type name within its package. It returns an +// empty string for unnamed types. It panics if s's kind is not struct. +func Name(s interface{}) string { + t := reflect.TypeOf(s) + + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + + if t.Kind() != reflect.Struct { + panic("not struct") + } + + return t.Name() +} + // 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 // in some of the functions. func strctInfo(s interface{}) (reflect.Value, []reflect.StructField) { - v := reflect.ValueOf(s) - - // if pointer get the underlying element≤ - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - - if v.Kind() != reflect.Struct { - panic("not struct") - } - + v := strctVal(s) t := v.Type() f := make([]reflect.StructField, 0) @@ -153,3 +159,18 @@ func strctInfo(s interface{}) (reflect.Value, []reflect.StructField) { return v, f } + +func strctVal(s interface{}) reflect.Value { + v := reflect.ValueOf(s) + + // if pointer get the underlying element≤ + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + if v.Kind() != reflect.Struct { + panic("not struct") + } + + return v +} diff --git a/structure_test.go b/structure_test.go index bcbac06..d27daa1 100644 --- a/structure_test.go +++ b/structure_test.go @@ -196,3 +196,16 @@ func TestIsValid(t *testing.T) { t.Error("IsValid should return false because F is not initialized") } } + +func TestName(t *testing.T) { + type Foo struct { + A string + B bool + } + f := &Foo{} + + n := Name(f) + if n != "Foo" { + t.Error("Name should return Foo, got: %s", n) + } +}