mirror of https://github.com/knative/docs.git
185 lines
5.2 KiB
Go
185 lines
5.2 KiB
Go
package spec
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/cloudevents/sdk-go/v2/event"
|
|
)
|
|
|
|
// Version provides meta-data for a single spec-version.
|
|
type Version interface {
|
|
// String name of the version, e.g. "1.0"
|
|
String() string
|
|
// Prefix for attribute names.
|
|
Prefix() string
|
|
// Attribute looks up a prefixed attribute name (case insensitive).
|
|
// Returns nil if not found.
|
|
Attribute(prefixedName string) Attribute
|
|
// Attribute looks up the attribute from kind.
|
|
// Returns nil if not found.
|
|
AttributeFromKind(kind Kind) Attribute
|
|
// Attributes returns all the context attributes for this version.
|
|
Attributes() []Attribute
|
|
// Convert translates a context to this version.
|
|
Convert(event.EventContextConverter) event.EventContext
|
|
// NewContext returns a new context for this version.
|
|
NewContext() event.EventContext
|
|
// SetAttribute sets named attribute to value.
|
|
//
|
|
// Name is case insensitive.
|
|
// Does nothing if name does not start with prefix.
|
|
SetAttribute(context event.EventContextWriter, name string, value interface{}) error
|
|
}
|
|
|
|
// Versions contains all known versions with the same attribute prefix.
|
|
type Versions struct {
|
|
prefix string
|
|
all []Version
|
|
m map[string]Version
|
|
}
|
|
|
|
// Versions returns the list of all known versions, most recent first.
|
|
func (vs *Versions) Versions() []Version { return vs.all }
|
|
|
|
// Version returns the named version.
|
|
func (vs *Versions) Version(name string) Version {
|
|
return vs.m[name]
|
|
}
|
|
|
|
// Latest returns the latest Version
|
|
func (vs *Versions) Latest() Version { return vs.all[0] }
|
|
|
|
// PrefixedSpecVersionName returns the specversion attribute PrefixedName
|
|
func (vs *Versions) PrefixedSpecVersionName() string { return vs.prefix + "specversion" }
|
|
|
|
// Prefix is the lowercase attribute name prefix.
|
|
func (vs *Versions) Prefix() string { return vs.prefix }
|
|
|
|
type attribute struct {
|
|
accessor
|
|
name string
|
|
version Version
|
|
}
|
|
|
|
func (a *attribute) PrefixedName() string { return a.version.Prefix() + a.name }
|
|
func (a *attribute) Name() string { return a.name }
|
|
func (a *attribute) Version() Version { return a.version }
|
|
|
|
type version struct {
|
|
prefix string
|
|
context event.EventContext
|
|
convert func(event.EventContextConverter) event.EventContext
|
|
attrMap map[string]Attribute
|
|
attrs []Attribute
|
|
}
|
|
|
|
func (v *version) Attribute(name string) Attribute { return v.attrMap[strings.ToLower(name)] }
|
|
func (v *version) Attributes() []Attribute { return v.attrs }
|
|
func (v *version) String() string { return v.context.GetSpecVersion() }
|
|
func (v *version) Prefix() string { return v.prefix }
|
|
func (v *version) NewContext() event.EventContext { return v.context.Clone() }
|
|
|
|
// HasPrefix is a case-insensitive prefix check.
|
|
func (v *version) HasPrefix(name string) bool {
|
|
return strings.HasPrefix(strings.ToLower(name), v.prefix)
|
|
}
|
|
|
|
func (v *version) Convert(c event.EventContextConverter) event.EventContext { return v.convert(c) }
|
|
|
|
func (v *version) SetAttribute(c event.EventContextWriter, name string, value interface{}) error {
|
|
if a := v.Attribute(name); a != nil { // Standard attribute
|
|
return a.Set(c, value)
|
|
}
|
|
name = strings.ToLower(name)
|
|
var err error
|
|
if v.HasPrefix(name) { // Extension attribute
|
|
return c.SetExtension(strings.TrimPrefix(name, v.prefix), value)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (v *version) AttributeFromKind(kind Kind) Attribute {
|
|
for _, a := range v.Attributes() {
|
|
if a.Kind() == kind {
|
|
return a
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func newVersion(
|
|
prefix string,
|
|
context event.EventContext,
|
|
convert func(event.EventContextConverter) event.EventContext,
|
|
attrs ...*attribute,
|
|
) *version {
|
|
v := &version{
|
|
prefix: strings.ToLower(prefix),
|
|
context: context,
|
|
convert: convert,
|
|
attrMap: map[string]Attribute{},
|
|
attrs: make([]Attribute, len(attrs)),
|
|
}
|
|
for i, a := range attrs {
|
|
a.version = v
|
|
v.attrs[i] = a
|
|
v.attrMap[strings.ToLower(a.PrefixedName())] = a
|
|
}
|
|
return v
|
|
}
|
|
|
|
// WithPrefix returns a set of versions with prefix added to all attribute names.
|
|
func WithPrefix(prefix string) *Versions {
|
|
attr := func(name string, kind Kind) *attribute {
|
|
return &attribute{accessor: acc[kind], name: name}
|
|
}
|
|
vs := &Versions{
|
|
m: map[string]Version{},
|
|
prefix: prefix,
|
|
all: []Version{
|
|
newVersion(prefix, event.EventContextV1{}.AsV1(),
|
|
func(c event.EventContextConverter) event.EventContext { return c.AsV1() },
|
|
attr("id", ID),
|
|
attr("source", Source),
|
|
attr("specversion", SpecVersion),
|
|
attr("type", Type),
|
|
attr("datacontenttype", DataContentType),
|
|
attr("dataschema", DataSchema),
|
|
attr("subject", Subject),
|
|
attr("time", Time),
|
|
),
|
|
newVersion(prefix, event.EventContextV03{}.AsV03(),
|
|
func(c event.EventContextConverter) event.EventContext { return c.AsV03() },
|
|
attr("specversion", SpecVersion),
|
|
attr("type", Type),
|
|
attr("source", Source),
|
|
attr("schemaurl", DataSchema),
|
|
attr("subject", Subject),
|
|
attr("id", ID),
|
|
attr("time", Time),
|
|
attr("datacontenttype", DataContentType),
|
|
),
|
|
},
|
|
}
|
|
for _, v := range vs.all {
|
|
vs.m[v.String()] = v
|
|
}
|
|
return vs
|
|
}
|
|
|
|
// New returns a set of versions
|
|
func New() *Versions { return WithPrefix("") }
|
|
|
|
// Built-in un-prefixed versions.
|
|
var (
|
|
VS *Versions
|
|
V03 Version
|
|
V1 Version
|
|
)
|
|
|
|
func init() {
|
|
VS = New()
|
|
V03 = VS.Version("0.3")
|
|
V1 = VS.Version("1.0")
|
|
}
|