Support for embedding interfaces.

This commit is contained in:
Alec Thomas
2018-09-12 13:18:52 +10:00
parent fd197e5081
commit 37d57a878b
3 changed files with 31 additions and 1 deletions
+2
View File
@@ -33,3 +33,5 @@ issues:
- 'Error return value of .(.*\.Help|.*\.MarkFlagRequired|(os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked'
- 'exported method (.*\.MarshalJSON|.*\.UnmarshalJSON) should have comment or be unexported'
- 'composite literal uses unkeyed fields'
- 'bad syntax for struct tag key'
- 'bad syntax for struct tag pair'
+6 -1
View File
@@ -42,17 +42,22 @@ type flattenedField struct {
}
func flattenedFields(v reflect.Value) (out []flattenedField) {
v = reflect.Indirect(v)
for i := 0; i < v.NumField(); i++ {
ft := v.Type().Field(i)
fv := v.Field(i)
tag := parseTag(fv, ft)
if ft.Anonymous {
if fv.Kind() == reflect.Interface {
fv = fv.Elem()
}
sub := flattenedFields(fv)
// Assign parent group to children, if they're not otherwise set.
for _, subf := range sub {
// Assign parent if it's not already set.
if subf.tag.Group == "" {
subf.tag.Group = tag.Group
}
// Accumulate prefixes.
subf.tag.Prefix = tag.Prefix + subf.tag.Prefix
}
out = append(out, sub...)
+23
View File
@@ -590,3 +590,26 @@ func TestAnonymousPrefix(t *testing.T) {
require.NoError(t, err)
require.Equal(t, "moo", cli.Flag)
}
type TestInterface interface {
SomeMethod()
}
type TestImpl struct {
Flag string
}
func (t *TestImpl) SomeMethod() {}
func TestEmbedInterface(t *testing.T) {
type CLI struct {
SomeFlag string
TestInterface
}
cli := &CLI{TestInterface: &TestImpl{}}
p := mustNew(t, cli)
_, err := p.Parse([]string{"--some-flag=foo", "--flag=yes"})
require.NoError(t, err)
require.Equal(t, "foo", cli.SomeFlag)
require.Equal(t, "yes", cli.TestInterface.(*TestImpl).Flag)
}