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>
This commit is contained in:
Mark Sagi-Kazar 2021-07-16 00:26:30 +02:00 committed by Márk Sági-Kazár
parent e54e7a53a5
commit 4b307cc0f3
6 changed files with 21 additions and 25 deletions

View file

@ -7,7 +7,7 @@ import (
// Encoder encodes the contents of v into a byte representation.
// It's primarily used for encoding a map[string]interface{} into a file format.
type Encoder interface {
Encode(v interface{}) ([]byte, error)
Encode(v map[string]interface{}) ([]byte, error)
}
const (
@ -47,7 +47,7 @@ func (e *EncoderRegistry) RegisterEncoder(format string, enc Encoder) error {
return nil
}
func (e *EncoderRegistry) Encode(format string, v interface{}) ([]byte, error) {
func (e *EncoderRegistry) Encode(format string, v map[string]interface{}) ([]byte, error) {
e.mu.RLock()
encoder, ok := e.encoders[format]
e.mu.RUnlock()

View file

@ -8,7 +8,7 @@ type encoder struct {
b []byte
}
func (e encoder) Encode(_ interface{}) ([]byte, error) {
func (e encoder) Encode(_ map[string]interface{}) ([]byte, error) {
return e.b, nil
}
@ -41,7 +41,7 @@ func TestEncoderRegistry_Decode(t *testing.T) {
t.Run("OK", func(t *testing.T) {
registry := NewEncoderRegistry()
encoder := encoder{
b: []byte("encoded value"),
b: []byte("key: value"),
}
err := registry.RegisterEncoder("myformat", encoder)
@ -49,20 +49,20 @@ func TestEncoderRegistry_Decode(t *testing.T) {
t.Fatal(err)
}
b, err := registry.Encode("myformat", "some value")
b, err := registry.Encode("myformat", map[string]interface{}{"key": "value"})
if err != nil {
t.Fatal(err)
}
if string(b) != "encoded value" {
t.Fatalf("expected 'encoded value', got: %#v", string(b))
if string(b) != "key: value" {
t.Fatalf("expected 'key: value', got: %#v", string(b))
}
})
t.Run("EncoderNotFound", func(t *testing.T) {
registry := NewEncoderRegistry()
_, err := registry.Encode("myformat", "some value")
_, err := registry.Encode("myformat", map[string]interface{}{"key": "value"})
if err != ErrEncoderNotFound {
t.Fatalf("expected ErrEncoderNotFound, got: %v", err)
}

View file

@ -12,7 +12,7 @@ import (
// TODO: add printer config to the codec?
type Codec struct{}
func (Codec) Encode(v interface{}) ([]byte, error) {
func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
b, err := json.Marshal(v)
if err != nil {
return nil, err

View file

@ -7,7 +7,7 @@ import (
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for JSON encoding.
type Codec struct{}
func (Codec) Encode(v interface{}) ([]byte, error) {
func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
// TODO: expose prefix and indent in the Codec as setting?
return json.MarshalIndent(v, "", " ")
}

View file

@ -7,22 +7,18 @@ import (
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for TOML encoding.
type Codec struct{}
func (Codec) Encode(v interface{}) ([]byte, error) {
if m, ok := v.(map[string]interface{}); ok {
t, err := toml.TreeFromMap(m)
if err != nil {
return nil, err
}
s, err := t.ToTomlString()
if err != nil {
return nil, err
}
return []byte(s), nil
func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
t, err := toml.TreeFromMap(v)
if err != nil {
return nil, err
}
return toml.Marshal(v)
s, err := t.ToTomlString()
if err != nil {
return nil, err
}
return []byte(s), nil
}
func (Codec) Decode(b []byte, v map[string]interface{}) error {

View file

@ -5,7 +5,7 @@ import "gopkg.in/yaml.v2"
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for YAML encoding.
type Codec struct{}
func (Codec) Encode(v interface{}) ([]byte, error) {
func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
return yaml.Marshal(v)
}