aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/alexflint/go-arg/sequence.go
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2024-10-25 00:47:47 +0200
committerMitja Felicijan <mitja.felicijan@gmail.com>2024-10-25 00:47:47 +0200
commitc6cc0108ca7738023b45e0eeac0fa2390532dd93 (patch)
tree36890e6cd3091bbab8efbe686cc56f467f645bfd /vendor/github.com/alexflint/go-arg/sequence.go
parent0130404a1dc663d4aa68d780c9bcb23a4243e68d (diff)
downloadjbmafp-c6cc0108ca7738023b45e0eeac0fa2390532dd93.tar.gz
Added vendor lock on depsHEADmaster
Diffstat (limited to 'vendor/github.com/alexflint/go-arg/sequence.go')
-rw-r--r--vendor/github.com/alexflint/go-arg/sequence.go123
1 files changed, 123 insertions, 0 deletions
diff --git a/vendor/github.com/alexflint/go-arg/sequence.go b/vendor/github.com/alexflint/go-arg/sequence.go
new file mode 100644
index 0000000..35a3614
--- /dev/null
+++ b/vendor/github.com/alexflint/go-arg/sequence.go
@@ -0,0 +1,123 @@
1package arg
2
3import (
4 "fmt"
5 "reflect"
6 "strings"
7
8 scalar "github.com/alexflint/go-scalar"
9)
10
11// setSliceOrMap parses a sequence of strings into a slice or map. If clear is
12// true then any values already in the slice or map are first removed.
13func setSliceOrMap(dest reflect.Value, values []string, clear bool) error {
14 if !dest.CanSet() {
15 return fmt.Errorf("field is not writable")
16 }
17
18 t := dest.Type()
19 if t.Kind() == reflect.Ptr {
20 dest = dest.Elem()
21 t = t.Elem()
22 }
23
24 switch t.Kind() {
25 case reflect.Slice:
26 return setSlice(dest, values, clear)
27 case reflect.Map:
28 return setMap(dest, values, clear)
29 default:
30 return fmt.Errorf("setSliceOrMap cannot insert values into a %v", t)
31 }
32}
33
34// setSlice parses a sequence of strings and inserts them into a slice. If clear
35// is true then any values already in the slice are removed.
36func setSlice(dest reflect.Value, values []string, clear bool) error {
37 var ptr bool
38 elem := dest.Type().Elem()
39 if elem.Kind() == reflect.Ptr && !elem.Implements(textUnmarshalerType) {
40 ptr = true
41 elem = elem.Elem()
42 }
43
44 // clear the slice in case default values exist
45 if clear && !dest.IsNil() {
46 dest.SetLen(0)
47 }
48
49 // parse the values one-by-one
50 for _, s := range values {
51 v := reflect.New(elem)
52 if err := scalar.ParseValue(v.Elem(), s); err != nil {
53 return err
54 }
55 if !ptr {
56 v = v.Elem()
57 }
58 dest.Set(reflect.Append(dest, v))
59 }
60 return nil
61}
62
63// setMap parses a sequence of name=value strings and inserts them into a map.
64// If clear is true then any values already in the map are removed.
65func setMap(dest reflect.Value, values []string, clear bool) error {
66 // determine the key and value type
67 var keyIsPtr bool
68 keyType := dest.Type().Key()
69 if keyType.Kind() == reflect.Ptr && !keyType.Implements(textUnmarshalerType) {
70 keyIsPtr = true
71 keyType = keyType.Elem()
72 }
73
74 var valIsPtr bool
75 valType := dest.Type().Elem()
76 if valType.Kind() == reflect.Ptr && !valType.Implements(textUnmarshalerType) {
77 valIsPtr = true
78 valType = valType.Elem()
79 }
80
81 // clear the slice in case default values exist
82 if clear && !dest.IsNil() {
83 for _, k := range dest.MapKeys() {
84 dest.SetMapIndex(k, reflect.Value{})
85 }
86 }
87
88 // allocate the map if it is not allocated
89 if dest.IsNil() {
90 dest.Set(reflect.MakeMap(dest.Type()))
91 }
92
93 // parse the values one-by-one
94 for _, s := range values {
95 // split at the first equals sign
96 pos := strings.Index(s, "=")
97 if pos == -1 {
98 return fmt.Errorf("cannot parse %q into a map, expected format key=value", s)
99 }
100
101 // parse the key
102 k := reflect.New(keyType)
103 if err := scalar.ParseValue(k.Elem(), s[:pos]); err != nil {
104 return err
105 }
106 if !keyIsPtr {
107 k = k.Elem()
108 }
109
110 // parse the value
111 v := reflect.New(valType)
112 if err := scalar.ParseValue(v.Elem(), s[pos+1:]); err != nil {
113 return err
114 }
115 if !valIsPtr {
116 v = v.Elem()
117 }
118
119 // add it to the map
120 dest.SetMapIndex(k, v)
121 }
122 return nil
123}