-
Notifications
You must be signed in to change notification settings - Fork 217
/
attributes.go
133 lines (113 loc) · 3.55 KB
/
attributes.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
package spec
import (
"fmt"
"time"
ce "github.com/cloudevents/sdk-go/pkg/cloudevents"
"github.com/cloudevents/sdk-go/pkg/cloudevents/types"
)
// Kind is a version-independent identifier for a CloudEvent context attribute.
type Kind uint8
const (
// Required cloudevents attributes
ID Kind = iota
Source
SpecVersion
Type
// Optional cloudevents attributes
DataContentType
DataSchema
Subject
Time
)
const nAttrs = int(Time) + 1
var kindNames = [nAttrs]string{
"id",
"source",
"specversion",
"type",
"datacontenttype",
"dataschema",
"subject",
"time",
}
// String is a human-readable string, for a valid attribute name use Attribute.Name
func (k Kind) String() string { return kindNames[k] }
// IsRequired returns true for attributes defined as "required" by the CE spec.
func (k Kind) IsRequired() bool { return k < DataContentType }
// Attribute is a named attribute accessor.
// The attribute name is specific to a Version.
type Attribute interface {
Kind() Kind
// Name of the attribute with respect to the current spec Version()
Name() string
// Version of the spec that this attribute belongs to
Version() Version
// Get the value of this attribute from an event context
Get(ce.EventContextReader) interface{}
// Set the value of this attribute on an event context
Set(ce.EventContextWriter, interface{}) error
// Delete this attribute from and event context, when possible
Delete(ce.EventContextWriter) error
}
// accessor provides Kind, Get, Set.
type accessor interface {
Kind() Kind
Get(ce.EventContextReader) interface{}
Set(ce.EventContextWriter, interface{}) error
Delete(ce.EventContextWriter) error
}
var acc = [nAttrs]accessor{
&aStr{aKind(ID), ce.EventContextReader.GetID, ce.EventContextWriter.SetID},
&aStr{aKind(Source), ce.EventContextReader.GetSource, ce.EventContextWriter.SetSource},
&aStr{aKind(SpecVersion), ce.EventContextReader.GetSpecVersion, ce.EventContextWriter.SetSpecVersion},
&aStr{aKind(Type), ce.EventContextReader.GetType, ce.EventContextWriter.SetType},
&aStr{aKind(DataContentType), ce.EventContextReader.GetDataContentType, ce.EventContextWriter.SetDataContentType},
&aStr{aKind(DataSchema), ce.EventContextReader.GetDataSchema, ce.EventContextWriter.SetDataSchema},
&aStr{aKind(Subject), ce.EventContextReader.GetSubject, ce.EventContextWriter.SetSubject},
&aTime{aKind(Time), ce.EventContextReader.GetTime, ce.EventContextWriter.SetTime},
}
// aKind implements Kind()
type aKind Kind
func (kind aKind) Kind() Kind { return Kind(kind) }
type aStr struct {
aKind
get func(ce.EventContextReader) string
set func(ce.EventContextWriter, string) error
}
func (a *aStr) Get(c ce.EventContextReader) interface{} {
if s := a.get(c); s != "" {
return s
}
return nil // Treat blank as missing
}
func (a *aStr) Set(c ce.EventContextWriter, v interface{}) error {
s, err := types.ToString(v)
if err != nil {
return fmt.Errorf("invalid value for %s: %#v", a.Kind(), v)
}
return a.set(c, s)
}
func (a *aStr) Delete(c ce.EventContextWriter) error {
return a.set(c, "")
}
type aTime struct {
aKind
get func(ce.EventContextReader) time.Time
set func(ce.EventContextWriter, time.Time) error
}
func (a *aTime) Get(c ce.EventContextReader) interface{} {
if v := a.get(c); !v.IsZero() {
return v
}
return nil // Treat zero time as missing.
}
func (a *aTime) Set(c ce.EventContextWriter, v interface{}) error {
t, err := types.ToTime(v)
if err != nil {
return fmt.Errorf("invalid value for %s: %#v", a.Kind(), v)
}
return a.set(c, t)
}
func (a *aTime) Delete(c ce.EventContextWriter) error {
return a.set(c, time.Time{})
}