generated from TBD54566975/tbd-project-template
-
Notifications
You must be signed in to change notification settings - Fork 7
/
request_name.go
117 lines (101 loc) · 2.54 KB
/
request_name.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
package model
import (
"crypto/rand"
"database/sql"
"database/sql/driver"
"encoding"
"encoding/hex"
"fmt"
"regexp"
"strings"
"github.com/alecthomas/errors"
"github.com/alecthomas/types"
)
// A RequestName represents an inbound request into the cluster.
type RequestName string
type MaybeRequestName types.Option[RequestName]
var _ interface {
sql.Scanner
driver.Valuer
encoding.TextUnmarshaler
encoding.TextMarshaler
} = (*RequestName)(nil)
type Origin string
const (
OriginIngress Origin = "ingress"
OriginCron Origin = "cron"
OriginPubsub Origin = "pubsub"
)
func ParseOrigin(origin string) (Origin, error) {
switch origin {
case "ingress":
return OriginIngress, nil
case "cron":
return OriginCron, nil
case "pubsub":
return OriginPubsub, nil
default:
return "", errors.Errorf("unknown origin %q", origin)
}
}
var requestNameNormaliserRe = regexp.MustCompile("[^a-zA-Z0-9]+")
func NewRequestName(origin Origin, key string) RequestName {
hash := make([]byte, 5)
_, err := rand.Read(hash)
if err != nil {
panic(err)
}
key = requestNameNormaliserRe.ReplaceAllString(key, "-")
key = strings.ToLower(key)
return RequestName(fmt.Sprintf("%s-%s-%010x", origin, key, hash))
}
func ParseRequestName(name string) (Origin, RequestName, error) {
parts := strings.Split(name, "-")
if len(parts) < 3 {
return "", "", errors.Errorf("should be <origin>-<key>-<hash>: invalid request name %q", name)
}
origin, err := ParseOrigin(parts[0])
if err != nil {
return "", "", errors.Wrapf(err, "invalid request name %q", name)
}
hash, err := hex.DecodeString(parts[len(parts)-1])
if err != nil {
return "", "", errors.Wrapf(err, "invalid request name %q", name)
}
if len(hash) != 5 {
return "", "", errors.Errorf("hash should be 5 bytes: invalid request name %q", name)
}
return origin, RequestName(fmt.Sprintf("%s-%010x", strings.Join(parts[0:len(parts)-1], "-"), hash)), nil
}
func (d *RequestName) String() string {
return string(*d)
}
func (d *RequestName) UnmarshalText(bytes []byte) error {
_, name, err := ParseRequestName(string(bytes))
if err != nil {
return err
}
*d = name
return nil
}
func (d *RequestName) MarshalText() ([]byte, error) {
return []byte(*d), nil
}
func (d *RequestName) Scan(value any) error {
if value == nil {
return nil
}
str, ok := value.(string)
if !ok {
return errors.Errorf("expected string, got %T", value)
}
_, name, err := ParseRequestName(str)
if err != nil {
return err
}
*d = name
return nil
}
func (d *RequestName) Value() (driver.Value, error) {
return d.String(), nil
}