diff options
| author | Alex Flint <[email protected]> | 2019-05-02 09:28:17 -0700 |
|---|---|---|
| committer | Alex Flint <[email protected]> | 2019-05-02 09:28:17 -0700 |
| commit | 87be2d97907952e87203bd3a4b09cfbe49ce028d (patch) | |
| tree | 7249020e562813f5a77467474f6f09d2c6375e82 /reflect.go | |
| parent | 5b649de04338e2ce398b9b1de3dc5f16144bdcd4 (diff) | |
add unittests for canParse
Diffstat (limited to 'reflect.go')
| -rw-r--r-- | reflect.go | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/reflect.go b/reflect.go new file mode 100644 index 0000000..32efe04 --- /dev/null +++ b/reflect.go @@ -0,0 +1,64 @@ +package arg + +import ( + "encoding" + "reflect" + + scalar "github.com/alexflint/go-scalar" +) + +var textUnmarshalerType = reflect.TypeOf([]encoding.TextUnmarshaler{}).Elem() + +// This file contains miscellaneous reflection utilities + +// canParse returns true if the type can be parsed from a string +func canParse(t reflect.Type) (parseable, boolean, multiple bool) { + parseable = scalar.CanParse(t) + boolean = isBoolean(t) + if parseable { + return + } + + // Look inside pointer types + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + // Look inside slice types + if t.Kind() == reflect.Slice { + multiple = true + t = t.Elem() + } + + parseable = scalar.CanParse(t) + boolean = isBoolean(t) + if parseable { + return + } + + // Look inside pointer types (again, in case of []*Type) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + + parseable = scalar.CanParse(t) + boolean = isBoolean(t) + if parseable { + return + } + + return false, false, false +} + +// isBoolean returns true if the type can be parsed from a single string +func isBoolean(t reflect.Type) bool { + switch { + case t.Implements(textUnmarshalerType): + return false + case t.Kind() == reflect.Bool: + return true + case t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Bool: + return true + default: + return false + } +} |
