forked from stripe/stripe-go
/
params.go
129 lines (109 loc) · 2.99 KB
/
params.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package stripe
import (
"crypto/rand"
"encoding/base64"
"fmt"
"net/url"
"strconv"
"time"
)
const (
startafter = "starting_after"
endbefore = "ending_before"
)
// Params is the structure that contains the common properties
// of any *Params structure.
type Params struct {
Exp []string
Meta map[string]string
IdempotencyKey string
}
// ListParams is the structure that contains the common properties
// of any *ListParams structure.
type ListParams struct {
Start, End string
Limit int
Filters Filters
// By default, listing through an iterator will automatically grab
// additional pages as the query progresses. To change this behavior
// and just load a single page, set this to true.
Single bool
}
// ListMeta is the structure that contains the common properties
// of List iterators. The Count property is only populated if the
// total_count include option is passed in (see tests for example).
type ListMeta struct {
Count uint16 `json:"total_count"`
More bool `json:"has_more"`
URL string `json:"url"`
}
// Filters is a structure that contains a collection of filters for list-related APIs.
type Filters struct {
f []*filter
}
// filter is the structure that contains a filter for list-related APIs.
// It ends up passing query string parameters in the format key[op]=value.
type filter struct {
Key, Op, Val string
}
// NewIdempotencyKey generates a new idempotency key that
// can be used on a request.
func NewIdempotencyKey() string {
now := time.Now().UnixNano()
buf := make([]byte, 4)
rand.Read(buf)
return fmt.Sprintf("%v_%v", now, base64.URLEncoding.EncodeToString(buf)[:6])
}
// Expand appends a new field to expand.
func (p *Params) Expand(f string) {
p.Exp = append(p.Exp, f)
}
// AddMeta adds a new key-value pair to the Metadata.
func (p *Params) AddMeta(key, value string) {
if p.Meta == nil {
p.Meta = make(map[string]string)
}
p.Meta[key] = value
}
// AddFilter adds a new filter with a given key, op and value.
func (f *Filters) AddFilter(key, op, value string) {
filter := &filter{Key: key, Op: op, Val: value}
f.f = append(f.f, filter)
}
// AppendTo adds the common parameters to the query string values.
func (p *Params) AppendTo(body *url.Values) {
for k, v := range p.Meta {
body.Add(fmt.Sprintf("metadata[%v]", k), v)
}
for _, v := range p.Exp {
body.Add("expand[]", v)
}
}
// AppendTo adds the common parameters to the query string values.
func (p *ListParams) AppendTo(body *url.Values) {
if len(p.Filters.f) > 0 {
p.Filters.AppendTo(body)
}
if len(p.Start) > 0 {
body.Add(startafter, p.Start)
}
if len(p.End) > 0 {
body.Add(endbefore, p.End)
}
if p.Limit > 0 {
if p.Limit > 100 {
p.Limit = 100
}
body.Add("limit", strconv.Itoa(p.Limit))
}
}
// AppendTo adds the list of filters to the query string values.
func (f *Filters) AppendTo(values *url.Values) {
for _, v := range f.f {
if len(v.Op) > 0 {
values.Add(fmt.Sprintf("%v[%v]", v.Key, v.Op), v.Val)
} else {
values.Add(v.Key, v.Val)
}
}
}