diff options
| author | Alex Flint <[email protected]> | 2019-08-06 16:58:46 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-08-06 16:58:46 -0700 |
| commit | 8baf7040d76473dd1d78c17b490d9d8cf6b1c584 (patch) | |
| tree | f3adbffc0cfcd02f559bbb1b1729e7f0a5b3ae35 /reflect.go | |
| parent | 6de9e789a982b5708c535308315c3d1d54217612 (diff) | |
| parent | 11a27074fcbbcce6d5b2129c9d33328152cd56be (diff) | |
Merge pull request #82 from alexflint/subcommand-implv1.1.0
Add support for subcommands
Diffstat (limited to 'reflect.go')
| -rw-r--r-- | reflect.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/reflect.go b/reflect.go new file mode 100644 index 0000000..e113583 --- /dev/null +++ b/reflect.go @@ -0,0 +1,62 @@ +package arg + +import ( + "encoding" + "reflect" + + scalar "github.com/alexflint/go-scalar" +) + +var textUnmarshalerType = reflect.TypeOf([]encoding.TextUnmarshaler{}).Elem() + +// 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 + } +} |
