-
Notifications
You must be signed in to change notification settings - Fork 1
/
client.go
148 lines (123 loc) · 3.14 KB
/
client.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
package recur
import (
"fmt"
"io"
"io/ioutil"
"os"
"time"
"github.com/BTBurke/recur/backend/stripe"
log "github.com/sirupsen/logrus"
)
// ClientType enumerates possible backends services (Stripe only for now)
type ClientType int
const (
// Use Stripe as the backend for recurring billing
StripeClient ClientType = iota
)
type runMode int
const (
runAsService runMode = iota
runAsLibrary
)
// Client
type Client struct {
Key string
Backend ClientType
Timeout time.Duration
Logger *log.Logger
Plan *PlanClient
runMode runMode
}
// ClientOption is a function that applies an option to the client configuration
type ClientOption func(c *Client) error
// NewClient returns a new client using the chosen service (e.g. Stripe) as the backend. Call this
// to create a client when using recur as a library in your own Go project. Use ClientOption
// to configure optional behavior such as logging (disabled by default).
func NewClient(service ClientType, key string, opts ...ClientOption) (*Client, error) {
return newClient(service, key, runAsLibrary, opts...)
}
// NewGRPCClient returns a new client using the chosen service (e.g. Stripe) as the backend. Call this
// to create a client when using recur as a microservice. Use ClientOption
// to configure optional behavior. Logging is enabled at INFO by default to Stdout.
func NewGRPCClient(service ClientType, key string, opts ...ClientOption) (*Client, error) {
return newClient(service, key, runAsService, opts...)
}
func newClient(service ClientType, key string, run runMode, opts ...ClientOption) (*Client, error) {
c := &Client{
Key: key,
runMode: run,
Logger: log.New(),
}
defaultOpts := []ClientOption{
LogLevel(LogLevelInfo),
LogFormat(TextFormatter),
}
switch run {
case runAsLibrary:
defaultOpts = append(defaultOpts, NoLog())
default:
defaultOpts = append(defaultOpts, LogOutput(os.Stdout))
}
for _, opt := range opts {
if err := opt(c); err != nil {
return nil, err
}
}
switch service {
case StripeClient:
c.Plan = &PlanClient{backend: stripe.NewPlanClient(key, c.Logger)}
return c, nil
default:
return nil, fmt.Errorf("unknown backend service")
}
}
func NoLog() ClientOption {
return func(c *Client) error {
c.Logger.Out = ioutil.Discard
return nil
}
}
type LoggerLevel int
const (
LogLevelDebug LoggerLevel = iota
LogLevelInfo
LogLevelWarn
LogLevelError
)
func LogLevel(level LoggerLevel) ClientOption {
return func(c *Client) error {
switch level {
case LogLevelDebug:
c.Logger.Level = log.DebugLevel
case LogLevelInfo:
c.Logger.Level = log.InfoLevel
case LogLevelWarn:
c.Logger.Level = log.WarnLevel
case LogLevelError:
c.Logger.Level = log.ErrorLevel
}
return nil
}
}
type LoggerFormat int
const (
JSONFormatter LoggerFormat = iota
TextFormatter
)
func LogFormat(f LoggerFormat) ClientOption {
return func(c *Client) error {
switch f {
case JSONFormatter:
c.Logger.Formatter = new(log.JSONFormatter)
case TextFormatter:
c.Logger.Formatter = new(log.TextFormatter)
}
return nil
}
}
func LogOutput(w io.Writer) ClientOption {
return func(c *Client) error {
c.Logger.Out = w
return nil
}
}