func (ec EventContextV03) Validate() ValidationError {
	errors := map[string]error{}
	eventType := strings.TrimSpace(ec.Type)
	if eventType == "" {
		errors["type"] = fmt.Errorf("MUST be a non-empty string")
	}
	source := strings.TrimSpace(ec.Source.String())
	if source == "" {
		errors["source"] = fmt.Errorf("REQUIRED")
	}
	if ec.Subject != nil {
		subject := strings.TrimSpace(*ec.Subject)
		if subject == "" {
			errors["subject"] = fmt.Errorf("if present, MUST be a non-empty string")
		}
	}
	id := strings.TrimSpace(ec.ID)
	if id == "" {
		errors["id"] = fmt.Errorf("MUST be a non-empty string")
	}
	if ec.SchemaURL != nil {
		schemaURL := strings.TrimSpace(ec.SchemaURL.String())
		if schemaURL == "" {
			errors["schemaurl"] = fmt.Errorf("if present, MUST adhere to the format specified in RFC 3986")
		}
	}
	if ec.DataContentType != nil {
		dataContentType := strings.TrimSpace(*ec.DataContentType)
		if dataContentType == "" {
			errors["datacontenttype"] = fmt.Errorf("if present, MUST adhere to the format specified in RFC 2046")
		} else {
			_, _, err := mime.ParseMediaType(dataContentType)
			if err != nil {
				errors["datacontenttype"] = fmt.Errorf("if present, MUST adhere to the format specified in RFC 2046")
			}
		}
	}
	if ec.DataContentEncoding != nil {
		dataContentEncoding := strings.ToLower(strings.TrimSpace(*ec.DataContentEncoding))
		if dataContentEncoding != Base64 {
			errors["datacontentencoding"] = fmt.Errorf("if present, MUST adhere to RFC 2045 Section 6.1")
		}
	}
	if len(errors) > 0 {
		return errors
	}
	return nil
}
Validate returns errors based on requirements from the CloudEvents spec.
For more details, see https://github.com/cloudevents/spec/blob/master/spec.md
As of Feb 26, 2019, commit 17c32ea26baf7714ad027d9917d03d2fff79fc7e
+ https://github.com/cloudevents/spec/pull/387 -> datacontentencoding
+ https://github.com/cloudevents/spec/pull/406 -> subject
package event
import (
	"encoding/json"
	"fmt"
	"mime"
	"sort"
	"strings"
	"github.com/cloudevents/sdk-go/v2/types"
)
const (
	CloudEventsVersionV03 = "0.3"
)
type EventContextV03 struct {
	Type string `json:"type"`
	Source types.URIRef `json:"source"`
	Subject *string `json:"subject,omitempty"`
	ID string `json:"id"`
	Time *types.Timestamp `json:"time,omitempty"`
	SchemaURL *types.URIRef `json:"schemaurl,omitempty"`
	DataContentType *string `json:"datacontenttype,omitempty"`
	DataContentEncoding *string `json:"datacontentencoding,omitempty"`
	Extensions map[string]interface{} `json:"-"`
}
var _ EventContext = (*EventContextV03)(nil)
func (ec EventContextV03) ExtensionAs(name string, obj interface{}) error {
	value, ok := ec.Extensions[name]
	if !ok {
		return fmt.Errorf("extension %q does not exist", name)
	}
	switch v := value.(type) {
	case json.RawMessage:
		if err := json.Unmarshal(v, obj); err == nil {
			return nil
		}
	}
	switch v := obj.(type) {
	case *string:
		if valueAsString, ok := value.(string); ok {
			*v = valueAsString
			return nil
		} else {
			return fmt.Errorf("invalid type for extension %q", name)
		}
	default:
		return fmt.Errorf("unknown extension type %T", obj)
	}
}
func (ec *EventContextV03) SetExtension(name string, value interface{}) error {
	if ec.Extensions == nil {
		ec.Extensions = make(map[string]interface{})
	}
	if value == nil {
		delete(ec.Extensions, name)
		if len(ec.Extensions) == 0 {
			ec.Extensions = nil
		}
		return nil
	} else {
		v, err := types.Validate(value)
		if err == nil {
			ec.Extensions[name] = v
		}
		return err
	}
}
func (ec EventContextV03) Clone() EventContext {
	ec03 := ec.AsV03()
	ec03.Source = types.Clone(ec.Source).(types.URIRef)
	if ec.Time != nil {
		ec03.Time = types.Clone(ec.Time).(*types.Timestamp)
	}
	if ec.SchemaURL != nil {
		ec03.SchemaURL = types.Clone(ec.SchemaURL).(*types.URIRef)
	}
	ec03.Extensions = ec.cloneExtensions()
	return ec03
}
func (ec *EventContextV03) cloneExtensions() map[string]interface{} {
	old := ec.Extensions
	if old == nil {
		return nil
	}
	new := make(map[string]interface{}, len(ec.Extensions))
	for k, v := range old {
		new[k] = types.Clone(v)
	}
	return new
}
func (ec EventContextV03) AsV03() *EventContextV03 {
	return &ec
}
func (ec EventContextV03) AsV1() *EventContextV1 {
	ret := EventContextV1{
		ID:              ec.ID,
		Time:            ec.Time,
		Type:            ec.Type,
		DataContentType: ec.DataContentType,
		Source:          types.URIRef{URL: ec.Source.URL},
		Subject:         ec.Subject,
		Extensions:      make(map[string]interface{}),
	}
	if ec.SchemaURL != nil {
		ret.DataSchema = &types.URI{URL: ec.SchemaURL.URL}
	}
	if ec.DataContentEncoding != nil {
		_ = ret.SetExtension(DataContentEncodingKey, *ec.DataContentEncoding)
	}
	if ec.Extensions != nil {
		for k, v := range ec.Extensions {
			k = strings.ToLower(k)
			ret.Extensions[k] = v
		}
	}
	if len(ret.Extensions) == 0 {
		ret.Extensions = nil
	}
	return &ret
}