feat(encoding)!: accept a map in the encoder interface
This interface is specific to encoding data from Viper's internal,
so it's okay to make it Viper specific.
BREAKING CHANGE: the encoder interface now accepts a map instead of an interface
Signed-off-by: Mark Sagi-Kazar <mark.sagikazar@gmail.com>
Mark Sagi-Kazar authored 2 years ago
Márk Sági-Kazár committed 2 years ago
6 | 6 | // Encoder encodes the contents of v into a byte representation. |
7 | 7 | // It's primarily used for encoding a map[string]interface{} into a file format. |
8 | 8 | type Encoder interface { |
9 | Encode(v interface{}) ([]byte, error) | |
9 | Encode(v map[string]interface{}) ([]byte, error) | |
10 | 10 | } |
11 | 11 | |
12 | 12 | const ( |
46 | 46 | return nil |
47 | 47 | } |
48 | 48 | |
49 | func (e *EncoderRegistry) Encode(format string, v interface{}) ([]byte, error) { | |
49 | func (e *EncoderRegistry) Encode(format string, v map[string]interface{}) ([]byte, error) { | |
50 | 50 | e.mu.RLock() |
51 | 51 | encoder, ok := e.encoders[format] |
52 | 52 | e.mu.RUnlock() |
7 | 7 | b []byte |
8 | 8 | } |
9 | 9 | |
10 | func (e encoder) Encode(_ interface{}) ([]byte, error) { | |
10 | func (e encoder) Encode(_ map[string]interface{}) ([]byte, error) { | |
11 | 11 | return e.b, nil |
12 | 12 | } |
13 | 13 | |
40 | 40 | t.Run("OK", func(t *testing.T) { |
41 | 41 | registry := NewEncoderRegistry() |
42 | 42 | encoder := encoder{ |
43 | b: []byte("encoded value"), | |
43 | b: []byte("key: value"), | |
44 | 44 | } |
45 | 45 | |
46 | 46 | err := registry.RegisterEncoder("myformat", encoder) |
48 | 48 | t.Fatal(err) |
49 | 49 | } |
50 | 50 | |
51 | b, err := registry.Encode("myformat", "some value") | |
51 | b, err := registry.Encode("myformat", map[string]interface{}{"key": "value"}) | |
52 | 52 | if err != nil { |
53 | 53 | t.Fatal(err) |
54 | 54 | } |
55 | 55 | |
56 | if string(b) != "encoded value" { | |
57 | t.Fatalf("expected 'encoded value', got: %#v", string(b)) | |
56 | if string(b) != "key: value" { | |
57 | t.Fatalf("expected 'key: value', got: %#v", string(b)) | |
58 | 58 | } |
59 | 59 | }) |
60 | 60 | |
61 | 61 | t.Run("EncoderNotFound", func(t *testing.T) { |
62 | 62 | registry := NewEncoderRegistry() |
63 | 63 | |
64 | _, err := registry.Encode("myformat", "some value") | |
64 | _, err := registry.Encode("myformat", map[string]interface{}{"key": "value"}) | |
65 | 65 | if err != ErrEncoderNotFound { |
66 | 66 | t.Fatalf("expected ErrEncoderNotFound, got: %v", err) |
67 | 67 | } |
11 | 11 | // TODO: add printer config to the codec? |
12 | 12 | type Codec struct{} |
13 | 13 | |
14 | func (Codec) Encode(v interface{}) ([]byte, error) { | |
14 | func (Codec) Encode(v map[string]interface{}) ([]byte, error) { | |
15 | 15 | b, err := json.Marshal(v) |
16 | 16 | if err != nil { |
17 | 17 | return nil, err |
6 | 6 | // Codec implements the encoding.Encoder and encoding.Decoder interfaces for JSON encoding. |
7 | 7 | type Codec struct{} |
8 | 8 | |
9 | func (Codec) Encode(v interface{}) ([]byte, error) { | |
9 | func (Codec) Encode(v map[string]interface{}) ([]byte, error) { | |
10 | 10 | // TODO: expose prefix and indent in the Codec as setting? |
11 | 11 | return json.MarshalIndent(v, "", " ") |
12 | 12 | } |
6 | 6 | // Codec implements the encoding.Encoder and encoding.Decoder interfaces for TOML encoding. |
7 | 7 | type Codec struct{} |
8 | 8 | |
9 | func (Codec) Encode(v interface{}) ([]byte, error) { | |
10 | if m, ok := v.(map[string]interface{}); ok { | |
11 | t, err := toml.TreeFromMap(m) | |
12 | if err != nil { | |
13 | return nil, err | |
14 | } | |
15 | ||
16 | s, err := t.ToTomlString() | |
17 | if err != nil { | |
18 | return nil, err | |
19 | } | |
20 | ||
21 | return []byte(s), nil | |
9 | func (Codec) Encode(v map[string]interface{}) ([]byte, error) { | |
10 | t, err := toml.TreeFromMap(v) | |
11 | if err != nil { | |
12 | return nil, err | |
22 | 13 | } |
23 | 14 | |
24 | return toml.Marshal(v) | |
15 | s, err := t.ToTomlString() | |
16 | if err != nil { | |
17 | return nil, err | |
18 | } | |
19 | ||
20 | return []byte(s), nil | |
25 | 21 | } |
26 | 22 | |
27 | 23 | func (Codec) Decode(b []byte, v map[string]interface{}) error { |