diff options
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 + } +} |
