summaryrefslogtreecommitdiff
path: root/reflect.go
diff options
context:
space:
mode:
authorAlex Flint <[email protected]>2019-08-06 16:58:46 -0700
committerGitHub <[email protected]>2019-08-06 16:58:46 -0700
commit8baf7040d76473dd1d78c17b490d9d8cf6b1c584 (patch)
treef3adbffc0cfcd02f559bbb1b1729e7f0a5b3ae35 /reflect.go
parent6de9e789a982b5708c535308315c3d1d54217612 (diff)
parent11a27074fcbbcce6d5b2129c9d33328152cd56be (diff)
Merge pull request #82 from alexflint/subcommand-implv1.1.0
Add support for subcommands
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
+ }
+}