From e38f3cc12c2f1fe65cd76ed72d8ee04af6d42d28 Mon Sep 17 00:00:00 2001 From: James Shubin Date: Sun, 12 Nov 2023 16:14:38 -0500 Subject: [PATCH] lang: types: Let the fancy TypeOf method match interfaces This adds the functionality to match on interface kinds. --- lang/types/type.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/lang/types/type.go b/lang/types/type.go index aa72ca86..c6860509 100644 --- a/lang/types/type.go +++ b/lang/types/type.go @@ -86,6 +86,7 @@ func TypeOf(t reflect.Type) (*Type, error) { StructTagOpt(StructTag), StrictStructTagOpt(false), SkipBadStructFieldsOpt(false), + AllowInterfaceTypeOpt(false), } return ConfigurableTypeOf(t, opts...) } @@ -110,6 +111,7 @@ type typeOfOptions struct { structTag string strictStructTag bool skipBadStructFields bool + allowInterfaceType bool // 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 // repeating code for the different variants of it that we want. func ConfigurableTypeOf(t reflect.Type, opts ...TypeOfOption) (*Type, error) { @@ -145,6 +155,7 @@ func ConfigurableTypeOf(t reflect.Type, opts ...TypeOfOption) (*Type, error) { structTag: "", strictStructTag: false, skipBadStructFields: false, + allowInterfaceType: false, } for _, optionFunc := range opts { // apply the options optionFunc(options) @@ -289,7 +300,15 @@ func ConfigurableTypeOf(t reflect.Type, opts ...TypeOfOption) (*Type, error) { }, nil // 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: return nil, fmt.Errorf("unable to represent type of %s", typ.String())