-
Notifications
You must be signed in to change notification settings - Fork 2
/
encoding.go
109 lines (95 loc) · 2.03 KB
/
encoding.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
package encoding
import (
"bytes"
"fmt"
"io"
)
var codecs = make(map[string]Codec)
// Codec interface.
type Codec interface {
NewCodec() Codec
NewEncoder(w io.Writer) (Encoder, error)
NewDecoder(r io.Reader) (Decoder, error)
Encode(v interface{}) ([]byte, error)
Decode(b []byte, v interface{}) error
SetIndent(indent string) error
SetMapString() error
}
// Encoder interface.
type Encoder interface {
Encode(v interface{}) error
}
// Decoder interface.
type Decoder interface {
Decode(v interface{}) error
}
// Option variadic function.
type Option func(Codec) error
// Register codec.
func Register(name string, codec Codec) {
codecs[name] = codec
}
// Codecs registered.
func Codecs() []string {
l := []string{}
for a := range codecs {
l = append(l, a)
}
return l
}
// Registered is the algorithm registered.
func Registered(name string) error {
_, ok := codecs[name]
if !ok {
return fmt.Errorf("codec not registered: %s", name)
}
return nil
}
// NewCodec variadic constructor.
func NewCodec(name string, opts ...Option) (Codec, error) {
e, ok := codecs[name]
if !ok {
return nil, fmt.Errorf("codec not registered: %s", name)
}
e = e.NewCodec()
for _, opt := range opts {
if err := opt(e); err != nil {
return nil, err
}
}
return e, nil
}
// WithIndent indent output.
// Supported by JSON.
func WithIndent(indent string) Option {
return func(c Codec) error {
return c.SetIndent(indent)
}
}
// WithMapString convert map[interface{}]interface{} to map[string]interface{}.
// Suppored by YAML.
func WithMapString() Option {
return func(c Codec) error {
return c.SetMapString()
}
}
// Encode method.
func Encode(c Codec, v interface{}) ([]byte, error) {
var buf bytes.Buffer
e, err := c.NewEncoder(&buf)
if err != nil {
return nil, err
}
if err := e.Encode(v); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// Decode method.
func Decode(c Codec, encoded []byte, v interface{}) error {
d, err := c.NewDecoder(bytes.NewBuffer(encoded))
if err != nil {
return err
}
return d.Decode(v)
}