summaryrefslogtreecommitdiff
path: root/reflect.go
diff options
context:
space:
mode:
authorAlex Flint <[email protected]>2019-05-02 09:28:17 -0700
committerAlex Flint <[email protected]>2019-05-02 09:28:17 -0700
commit87be2d97907952e87203bd3a4b09cfbe49ce028d (patch)
tree7249020e562813f5a77467474f6f09d2c6375e82 /reflect.go
parent5b649de04338e2ce398b9b1de3dc5f16144bdcd4 (diff)
add unittests for canParse
Diffstat (limited to 'reflect.go')
-rw-r--r--reflect.go64
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
+ }
+}