-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathvalues.go
104 lines (87 loc) · 2.37 KB
/
values.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package client
import (
"fmt"
"net/url"
"strings"
)
// Values is a modified, Ponzu-specific version of the Go standard library's
// url.Values, which implements most all of the same behavior. The exceptions are
// that its `Add(k, v string)` method converts keys into the expected format for
// Ponzu data containing slice type fields, and the `Get(k string)` method returns
// an `interface{}` which will either assert to a `string` or `[]string`.
type Values struct {
values url.Values
keyIndex map[string]int
}
// Add updates the Values by including a properly formatted form value to data Values.
func (v *Values) Add(key, value string) {
if v.keyIndex[key] == 0 {
v.values.Set(key, value)
v.keyIndex[key]++
return
}
if v.keyIndex[key] == 1 {
val := v.values.Get(key)
v.values.Del(key)
k := key + ".0"
v.values.Add(k, val)
}
keyIdx := fmt.Sprintf("%s.%d", key, v.keyIndex[key])
v.keyIndex[key]++
v.values.Set(keyIdx, value)
}
// NewValues creates and returns an empty set of Ponzu values.
func NewValues() *Values {
return &Values{
values: make(url.Values),
keyIndex: make(map[string]int),
}
}
// Del deletes a key and its value(s) from the data set.
func (v *Values) Del(key string) {
if v.keyIndex[key] != 0 {
// delete all key.0, key.1, etc
n := v.keyIndex[key]
for i := 0; i < n; i++ {
v.values.Del(fmt.Sprintf("%s.%d", key, i))
v.keyIndex[key]--
}
v.keyIndex[key] = 0
return
}
v.values.Del(key)
v.keyIndex[key]--
}
// Encode prepares the data set into a URL query encoded string.
func (v *Values) Encode() string { return v.values.Encode() }
// Get returns an `interface{}` value for the key provided, which will assert to
// either a `string` or `[]string`.
func (v *Values) Get(key string) interface{} {
if strings.Contains(key, ".") {
return v.values.Get(key)
}
if v.keyIndex[key] == 0 {
return ""
}
if v.keyIndex[key] == 1 {
return v.values.Get(key)
}
var results []string
for i := 0; i < v.keyIndex[key]; i++ {
keyIdx := fmt.Sprintf("%s.%d", key, i)
results = append(results, v.values.Get(keyIdx))
}
return results
}
// Set sets a value for a key provided. If Set/Add has already been called, this
// will override all values at the key.
func (v *Values) Set(key, value string) {
if v.keyIndex[key] == 0 {
v.values.Set(key, value)
v.keyIndex[key]++
return
}
v.Del(key)
v.keyIndex[key] = 0
v.Set(key, value)
}