neero.*Client.newRequest   A
last analyzed

Complexity

Conditions 4

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 16
nop 4
dl 0
loc 23
rs 9.6
c 0
b 0
f 0
1
package neero
2
3
import (
4
	"bytes"
5
	"context"
6
	"encoding/json"
7
	"fmt"
8
	"io"
9
	"net/http"
10
)
11
12
type service struct {
13
	client *Client
14
}
15
16
// Client is the neero API client.
17
// Do not instantiate this client with Client{}. Use the New method instead.
18
type Client struct {
19
	common            service
20
	httpClient        *http.Client
21
	baseURL           string
22
	secretKey         string
23
	PaymentMethod     *paymentMethodService
24
	Balance           *balanceService
25
	TransactionIntent *transactionIntentService
26
}
27
28
// New creates and returns a new neero.Client from a slice of neero.ClientOption.
29
func New(options ...Option) *Client {
30
	config := defaultClientConfig()
31
32
	for _, option := range options {
33
		option.apply(config)
34
	}
35
36
	client := &Client{
37
		httpClient: config.httpClient,
38
		secretKey:  config.secretKey,
39
		baseURL:    config.baseURL,
40
	}
41
42
	client.common.client = client
43
	client.PaymentMethod = (*paymentMethodService)(&client.common)
44
	client.Balance = (*balanceService)(&client.common)
45
	client.TransactionIntent = (*transactionIntentService)(&client.common)
46
	return client
47
}
48
49
// newRequest creates an API request. A relative URL can be provided in uri,
50
// in which case it is resolved relative to the BaseURL of the Client.
51
// URI's should always be specified without a preceding slash.
52
func (client *Client) newRequest(ctx context.Context, method, uri string, body any) (*http.Request, error) {
53
	var buf io.ReadWriter
54
	if body != nil {
55
		buf = &bytes.Buffer{}
56
		enc := json.NewEncoder(buf)
57
		enc.SetEscapeHTML(false)
58
		err := enc.Encode(body)
59
		if err != nil {
60
			return nil, err
61
		}
62
	}
63
64
	req, err := http.NewRequestWithContext(ctx, method, client.baseURL+uri, buf)
65
	if err != nil {
66
		return nil, err
67
	}
68
69
	req.Header.Set("Content-Type", "application/json")
70
	req.Header.Set("Accept", "application/json")
71
72
	req.SetBasicAuth(client.secretKey, "")
73
74
	return req, nil
75
}
76
77
// do carries out an HTTP request and returns a Response
78
func (client *Client) do(req *http.Request) (*Response, error) {
79
	if req == nil {
80
		return nil, fmt.Errorf("%T cannot be nil", req)
81
	}
82
83
	httpResponse, err := client.httpClient.Do(req)
84
	if err != nil {
85
		return nil, err
86
	}
87
88
	defer func() { _ = httpResponse.Body.Close() }()
89
90
	resp, err := client.newResponse(httpResponse)
91
	if err != nil {
92
		return resp, err
93
	}
94
95
	_, err = io.Copy(io.Discard, httpResponse.Body)
96
	if err != nil {
97
		return resp, err
98
	}
99
100
	return resp, nil
101
}
102
103
// newResponse converts an *http.Response to *Response
104
func (client *Client) newResponse(httpResponse *http.Response) (*Response, error) {
105
	if httpResponse == nil {
106
		return nil, fmt.Errorf("%T cannot be nil", httpResponse)
107
	}
108
109
	resp := new(Response)
110
	resp.HTTPResponse = httpResponse
111
112
	buf, err := io.ReadAll(resp.HTTPResponse.Body)
113
	if err != nil {
114
		return nil, err
115
	}
116
	resp.Body = &buf
117
118
	return resp, resp.Error()
119
}
120