forked from stripe/stripe-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
params.go
150 lines (126 loc) · 3.44 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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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
Extra url.Values
IdempotencyKey, Account 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])
}
// SetAccount sets a value for the Stripe-Account header.
func (p *Params) SetAccount(val string) {
p.Account = val
}
// 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
}
// AddExtra adds a new arbitrary key-value pair to the request data
func (p *Params) AddExtra(key, value string) {
if p.Extra == nil {
p.Extra = make(url.Values)
}
p.Extra.Add(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)
}
for k, vs := range p.Extra {
for _, v := range vs {
body.Add(k, 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)
}
}
}