lang: types: Let the fancy TypeOf method match interfaces
This adds the functionality to match on interface kinds.
This commit is contained in:
@@ -86,6 +86,7 @@ func TypeOf(t reflect.Type) (*Type, error) {
|
|||||||
StructTagOpt(StructTag),
|
StructTagOpt(StructTag),
|
||||||
StrictStructTagOpt(false),
|
StrictStructTagOpt(false),
|
||||||
SkipBadStructFieldsOpt(false),
|
SkipBadStructFieldsOpt(false),
|
||||||
|
AllowInterfaceTypeOpt(false),
|
||||||
}
|
}
|
||||||
return ConfigurableTypeOf(t, opts...)
|
return ConfigurableTypeOf(t, opts...)
|
||||||
}
|
}
|
||||||
@@ -110,6 +111,7 @@ type typeOfOptions struct {
|
|||||||
structTag string
|
structTag string
|
||||||
strictStructTag bool
|
strictStructTag bool
|
||||||
skipBadStructFields bool
|
skipBadStructFields bool
|
||||||
|
allowInterfaceType bool
|
||||||
// TODO: add more options
|
// TODO: add more options
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +140,14 @@ func SkipBadStructFieldsOpt(skipBadStructFields bool) TypeOfOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AllowInterfaceTypeOpt specifies whether we should allow matching on an
|
||||||
|
// interface kind. This is used by ResTypeOf.
|
||||||
|
func AllowInterfaceTypeOpt(allowInterfaceType bool) TypeOfOption {
|
||||||
|
return func(opt *typeOfOptions) {
|
||||||
|
opt.allowInterfaceType = allowInterfaceType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ConfigurableTypeOf is a configurable version of the TypeOf function to avoid
|
// ConfigurableTypeOf is a configurable version of the TypeOf function to avoid
|
||||||
// repeating code for the different variants of it that we want.
|
// repeating code for the different variants of it that we want.
|
||||||
func ConfigurableTypeOf(t reflect.Type, opts ...TypeOfOption) (*Type, error) {
|
func ConfigurableTypeOf(t reflect.Type, opts ...TypeOfOption) (*Type, error) {
|
||||||
@@ -145,6 +155,7 @@ func ConfigurableTypeOf(t reflect.Type, opts ...TypeOfOption) (*Type, error) {
|
|||||||
structTag: "",
|
structTag: "",
|
||||||
strictStructTag: false,
|
strictStructTag: false,
|
||||||
skipBadStructFields: false,
|
skipBadStructFields: false,
|
||||||
|
allowInterfaceType: false,
|
||||||
}
|
}
|
||||||
for _, optionFunc := range opts { // apply the options
|
for _, optionFunc := range opts { // apply the options
|
||||||
optionFunc(options)
|
optionFunc(options)
|
||||||
@@ -289,7 +300,15 @@ func ConfigurableTypeOf(t reflect.Type, opts ...TypeOfOption) (*Type, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
|
|
||||||
// TODO: should this return a variant type?
|
// TODO: should this return a variant type?
|
||||||
//case reflect.Interface:
|
case reflect.Interface:
|
||||||
|
if !options.allowInterfaceType {
|
||||||
|
return nil, fmt.Errorf("unable to represent type of %s without AllowInterfaceTypeOpt", typ.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Type{
|
||||||
|
Kind: KindVariant,
|
||||||
|
Var: nil, // TODO: can we set this?
|
||||||
|
}, nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unable to represent type of %s", typ.String())
|
return nil, fmt.Errorf("unable to represent type of %s", typ.String())
|
||||||
|
|||||||
Reference in New Issue
Block a user