mirror of https://github.com/knative/docs.git
137 lines
3.8 KiB
Go
137 lines
3.8 KiB
Go
package spec
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/cloudevents/sdk-go/v2/event"
|
|
|
|
"github.com/cloudevents/sdk-go/v2/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() with prefix
|
|
PrefixedName() string
|
|
// 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(event.EventContextReader) interface{}
|
|
// Set the value of this attribute on an event context
|
|
Set(event.EventContextWriter, interface{}) error
|
|
// Delete this attribute from and event context, when possible
|
|
Delete(event.EventContextWriter) error
|
|
}
|
|
|
|
// accessor provides Kind, Get, Set.
|
|
type accessor interface {
|
|
Kind() Kind
|
|
Get(event.EventContextReader) interface{}
|
|
Set(event.EventContextWriter, interface{}) error
|
|
Delete(event.EventContextWriter) error
|
|
}
|
|
|
|
var acc = [nAttrs]accessor{
|
|
&aStr{aKind(ID), event.EventContextReader.GetID, event.EventContextWriter.SetID},
|
|
&aStr{aKind(Source), event.EventContextReader.GetSource, event.EventContextWriter.SetSource},
|
|
&aStr{aKind(SpecVersion), event.EventContextReader.GetSpecVersion, func(writer event.EventContextWriter, s string) error { return nil }},
|
|
&aStr{aKind(Type), event.EventContextReader.GetType, event.EventContextWriter.SetType},
|
|
&aStr{aKind(DataContentType), event.EventContextReader.GetDataContentType, event.EventContextWriter.SetDataContentType},
|
|
&aStr{aKind(DataSchema), event.EventContextReader.GetDataSchema, event.EventContextWriter.SetDataSchema},
|
|
&aStr{aKind(Subject), event.EventContextReader.GetSubject, event.EventContextWriter.SetSubject},
|
|
&aTime{aKind(Time), event.EventContextReader.GetTime, event.EventContextWriter.SetTime},
|
|
}
|
|
|
|
// aKind implements Kind()
|
|
type aKind Kind
|
|
|
|
func (kind aKind) Kind() Kind { return Kind(kind) }
|
|
|
|
type aStr struct {
|
|
aKind
|
|
get func(event.EventContextReader) string
|
|
set func(event.EventContextWriter, string) error
|
|
}
|
|
|
|
func (a *aStr) Get(c event.EventContextReader) interface{} {
|
|
if s := a.get(c); s != "" {
|
|
return s
|
|
}
|
|
return nil // Treat blank as missing
|
|
}
|
|
|
|
func (a *aStr) Set(c event.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 event.EventContextWriter) error {
|
|
return a.set(c, "")
|
|
}
|
|
|
|
type aTime struct {
|
|
aKind
|
|
get func(event.EventContextReader) time.Time
|
|
set func(event.EventContextWriter, time.Time) error
|
|
}
|
|
|
|
func (a *aTime) Get(c event.EventContextReader) interface{} {
|
|
if v := a.get(c); !v.IsZero() {
|
|
return v
|
|
}
|
|
return nil // Treat zero time as missing.
|
|
}
|
|
|
|
func (a *aTime) Set(c event.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 event.EventContextWriter) error {
|
|
return a.set(c, time.Time{})
|
|
}
|