-
Notifications
You must be signed in to change notification settings - Fork 216
/
codec.go
96 lines (82 loc) · 3.06 KB
/
codec.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
package datacodec
import (
"context"
"fmt"
"github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/json"
"github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/text"
"github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/xml"
"github.com/cloudevents/sdk-go/pkg/cloudevents/observability"
)
// Decoder is the expected function signature for decoding `in` to `out`. What
// `in` is could be decoder dependent. For example, `in` could be bytes, or a
// base64 string.
type Decoder func(ctx context.Context, in, out interface{}) error
// Encoder is the expected function signature for encoding `in` to bytes.
// Returns an error if the encoder has an issue encoding `in`.
type Encoder func(ctx context.Context, in interface{}) ([]byte, error)
var decoder map[string]Decoder
var encoder map[string]Encoder
func init() {
decoder = make(map[string]Decoder, 10)
encoder = make(map[string]Encoder, 10)
AddDecoder("", json.Decode)
AddDecoder("application/json", json.Decode)
AddDecoder("text/json", json.Decode)
AddDecoder("application/xml", xml.Decode)
AddDecoder("text/xml", xml.Decode)
AddDecoder("text/plain", text.Decode)
AddEncoder("", json.Encode)
AddEncoder("application/json", json.Encode)
AddEncoder("text/json", json.Encode)
AddEncoder("application/xml", xml.Encode)
AddEncoder("text/xml", xml.Encode)
AddEncoder("text/plain", text.Encode)
}
// AddDecoder registers a decoder for a given content type. The codecs will use
// these to decode the data payload from a cloudevent.Event object.
func AddDecoder(contentType string, fn Decoder) {
decoder[contentType] = fn
}
// AddEncoder registers an encoder for a given content type. The codecs will
// use these to encode the data payload for a cloudevent.Event object.
func AddEncoder(contentType string, fn Encoder) {
encoder[contentType] = fn
}
// Decode looks up and invokes the decoder registered for the given content
// type. An error is returned if no decoder is registered for the given
// content type.
func Decode(ctx context.Context, contentType string, in, out interface{}) error {
_, r := observability.NewReporter(ctx, reportDecode)
err := obsDecode(ctx, contentType, in, out)
if err != nil {
r.Error()
} else {
r.OK()
}
return err
}
func obsDecode(ctx context.Context, contentType string, in, out interface{}) error {
if fn, ok := decoder[contentType]; ok {
return fn(ctx, in, out)
}
return fmt.Errorf("[decode] unsupported content type: %q", contentType)
}
// Encode looks up and invokes the encoder registered for the given content
// type. An error is returned if no encoder is registered for the given
// content type.
func Encode(ctx context.Context, contentType string, in interface{}) ([]byte, error) {
_, r := observability.NewReporter(ctx, reportEncode)
b, err := obsEncode(ctx, contentType, in)
if err != nil {
r.Error()
} else {
r.OK()
}
return b, err
}
func obsEncode(ctx context.Context, contentType string, in interface{}) ([]byte, error) {
if fn, ok := encoder[contentType]; ok {
return fn(ctx, in)
}
return nil, fmt.Errorf("[encode] unsupported content type: %q", contentType)
}