1package httpbinding
2
3import (
4	"encoding/base64"
5	"math/big"
6	"net/http"
7	"strconv"
8	"strings"
9)
10
11// Headers is used to encode header keys using a provided prefix
12type Headers struct {
13	header http.Header
14	prefix string
15}
16
17// AddHeader returns a HeaderValue used to append values to prefix+key
18func (h Headers) AddHeader(key string) HeaderValue {
19	return h.newHeaderValue(key, true)
20}
21
22// SetHeader returns a HeaderValue used to set the value of prefix+key
23func (h Headers) SetHeader(key string) HeaderValue {
24	return h.newHeaderValue(key, false)
25}
26
27func (h Headers) newHeaderValue(key string, append bool) HeaderValue {
28	return newHeaderValue(h.header, h.prefix+strings.TrimSpace(key), append)
29}
30
31// HeaderValue is used to encode values to an HTTP header
32type HeaderValue struct {
33	header http.Header
34	key    string
35	append bool
36}
37
38func newHeaderValue(header http.Header, key string, append bool) HeaderValue {
39	return HeaderValue{header: header, key: strings.TrimSpace(key), append: append}
40}
41
42func (h HeaderValue) modifyHeader(value string) {
43	if h.append {
44		h.header[h.key] = append(h.header[h.key], value)
45	} else {
46		h.header[h.key] = append(h.header[h.key][:0], value)
47	}
48}
49
50// String encodes the value v as the header string value
51func (h HeaderValue) String(v string) {
52	h.modifyHeader(v)
53}
54
55// Byte encodes the value v as a query string value
56func (h HeaderValue) Byte(v int8) {
57	h.Long(int64(v))
58}
59
60// Short encodes the value v as a query string value
61func (h HeaderValue) Short(v int16) {
62	h.Long(int64(v))
63}
64
65// Integer encodes the value v as the header string value
66func (h HeaderValue) Integer(v int32) {
67	h.Long(int64(v))
68}
69
70// Long encodes the value v as the header string value
71func (h HeaderValue) Long(v int64) {
72	h.modifyHeader(strconv.FormatInt(v, 10))
73}
74
75// Boolean encodes the value v as a query string value
76func (h HeaderValue) Boolean(v bool) {
77	h.modifyHeader(strconv.FormatBool(v))
78}
79
80// Float encodes the value v as a query string value
81func (h HeaderValue) Float(v float32) {
82	h.float(float64(v), 32)
83}
84
85// Double encodes the value v as a query string value
86func (h HeaderValue) Double(v float64) {
87	h.float(v, 64)
88}
89
90func (h HeaderValue) float(v float64, bitSize int) {
91	h.modifyHeader(strconv.FormatFloat(v, 'f', -1, bitSize))
92}
93
94// BigInteger encodes the value v as a query string value
95func (h HeaderValue) BigInteger(v *big.Int) {
96	h.modifyHeader(v.String())
97}
98
99// BigDecimal encodes the value v as a query string value
100func (h HeaderValue) BigDecimal(v *big.Float) {
101	if i, accuracy := v.Int64(); accuracy == big.Exact {
102		h.Long(i)
103		return
104	}
105	h.modifyHeader(v.Text('e', -1))
106}
107
108// Blob encodes the value v as a base64 header string value
109func (h HeaderValue) Blob(v []byte) {
110	encodeToString := base64.StdEncoding.EncodeToString(v)
111	h.modifyHeader(encodeToString)
112}
113