summaryrefslogtreecommitdiff
path: root/reflect.go
diff options
context:
space:
mode:
Diffstat (limited to 'reflect.go')
-rw-r--r--reflect.go62
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
+ }
+}