diff --git a/structure.go b/structure.go index 94f0e3b..4b3fb39 100644 --- a/structure.go +++ b/structure.go @@ -194,6 +194,12 @@ func Has(s interface{}, fieldName string) bool { return false } +// Implements returns true if the given struct s implements the i interface +// type. +func Implements(s, i interface{}) bool { + return reflect.TypeOf(s).Implements(reflect.TypeOf(i).Elem()) +} + // 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. @@ -221,6 +227,21 @@ func strctInfo(s interface{}) (reflect.Value, []reflect.StructField) { return v, f } +func strctType(s interface{}) reflect.Type { + t := reflect.TypeOf(s) + + // if pointer get the underlying element≤ + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + + if t.Kind() != reflect.Struct { + panic("not struct") + } + + return t +} + func strctVal(s interface{}) reflect.Value { v := reflect.ValueOf(s) diff --git a/structure_example_test.go b/structure_example_test.go index dcb12ea..4fdbcd0 100644 --- a/structure_example_test.go +++ b/structure_example_test.go @@ -2,6 +2,7 @@ package structure import ( "fmt" + "io" "time" ) @@ -146,3 +147,28 @@ func ExampleHas() { // Output: // Has: true } + +type Bar struct{} + +func (b Bar) String() string { return "bar" } +func (b Bar) Write(p []byte) (n int, err error) { return 0, nil } + +func ExampleImplements() { + // type Bar struct{} + // + // func (b Bar) String() string { return "bar" } + // func (b Bar) Write(p []byte) (n int, err error) { return 0, nil } + b := Bar{} + + okA := Implements(b, new(fmt.Stringer)) + okB := Implements(b, new(io.Writer)) + okC := Implements(b, new(io.Reader)) + + fmt.Printf("Implements io.Writer: %+v\n", okA) + fmt.Printf("Implements io.Reader: %+v\n", okB) + fmt.Printf("Implements fmt.Stringer: %+v\n", okC) + // Output: + // Implements io.Writer: true + // Implements io.Reader: true + // Implements fmt.Stringer: false +} diff --git a/structure_test.go b/structure_test.go index 3980960..5795746 100644 --- a/structure_test.go +++ b/structure_test.go @@ -1,6 +1,8 @@ package structure import ( + "fmt" + "io" "reflect" "testing" ) @@ -471,3 +473,17 @@ func TestName(t *testing.T) { t.Error("Name should return empty string for unnamed struct, got: %s", n) } } + +type Foo struct{} + +func (f Foo) String() string { return "foo" } +func (f Foo) Write(p []byte) (n int, err error) { return 0, nil } + +func TestImplements(t *testing.T) { + f := Foo{} + + ok := Implements(f, new(io.Reader)) + + fmt.Printf("ok %+v\n", ok) + +}