Codebase list golang-github-spf13-viper / e54e7a5
feat(encoding)!: accept a map in the decoder interface This interface is specific to decoding data into Viper's internal, so it's okay to make it Viper specific. BREAKING CHANGE: the decoder 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
7 changed file(s) with 30 addition(s) and 31 deletion(s). Raw diff Collapse all Expand all
33 "sync"
44 )
55
6 // Decoder decodes the contents of b into a v representation.
6 // Decoder decodes the contents of b into v.
77 // It's primarily used for decoding contents of a file into a map[string]interface{}.
88 type Decoder interface {
9 Decode(b []byte, v interface{}) error
9 Decode(b []byte, v map[string]interface{}) error
1010 }
1111
1212 const (
4747 }
4848
4949 // Decode calls the underlying Decoder based on the format.
50 func (e *DecoderRegistry) Decode(format string, b []byte, v interface{}) error {
50 func (e *DecoderRegistry) Decode(format string, b []byte, v map[string]interface{}) error {
5151 e.mu.RLock()
5252 decoder, ok := e.decoders[format]
5353 e.mu.RUnlock()
00 package encoding
11
22 import (
3 "reflect"
34 "testing"
45 )
56
67 type decoder struct {
7 v interface{}
8 v map[string]interface{}
89 }
910
10 func (d decoder) Decode(_ []byte, v interface{}) error {
11 rv := v.(*string)
12 *rv = d.v.(string)
11 func (d decoder) Decode(_ []byte, v map[string]interface{}) error {
12 for key, value := range d.v {
13 v[key] = value
14 }
1315
1416 return nil
1517 }
4345 t.Run("OK", func(t *testing.T) {
4446 registry := NewDecoderRegistry()
4547 decoder := decoder{
46 v: "decoded value",
48 v: map[string]interface{}{
49 "key": "value",
50 },
4751 }
4852
4953 err := registry.RegisterDecoder("myformat", decoder)
5155 t.Fatal(err)
5256 }
5357
54 var v string
58 v := map[string]interface{}{}
5559
56 err = registry.Decode("myformat", []byte("some value"), &v)
60 err = registry.Decode("myformat", []byte("key: value"), v)
5761 if err != nil {
5862 t.Fatal(err)
5963 }
6064
61 if v != "decoded value" {
62 t.Fatalf("expected 'decoded value', got: %#v", v)
65 if !reflect.DeepEqual(decoder.v, v) {
66 t.Fatalf("decoded value does not match the expected one\nactual: %+v\nexpected: %+v", v, decoder.v)
6367 }
6468 })
6569
6670 t.Run("DecoderNotFound", func(t *testing.T) {
6771 registry := NewDecoderRegistry()
6872
69 var v string
73 v := map[string]interface{}{}
7074
71 err := registry.Decode("myformat", []byte("some value"), &v)
75 err := registry.Decode("myformat", nil, v)
7276 if err != ErrDecoderNotFound {
7377 t.Fatalf("expected ErrDecoderNotFound, got: %v", err)
7478 }
3434 return buf.Bytes(), nil
3535 }
3636
37 func (Codec) Decode(b []byte, v interface{}) error {
38 return hcl.Unmarshal(b, v)
37 func (Codec) Decode(b []byte, v map[string]interface{}) error {
38 return hcl.Unmarshal(b, &v)
3939 }
1111 return json.MarshalIndent(v, "", " ")
1212 }
1313
14 func (Codec) Decode(b []byte, v interface{}) error {
15 return json.Unmarshal(b, v)
14 func (Codec) Decode(b []byte, v map[string]interface{}) error {
15 return json.Unmarshal(b, &v)
1616 }
2424 return toml.Marshal(v)
2525 }
2626
27 func (Codec) Decode(b []byte, v interface{}) error {
27 func (Codec) Decode(b []byte, v map[string]interface{}) error {
2828 tree, err := toml.LoadBytes(b)
2929 if err != nil {
3030 return err
3131 }
3232
33 if m, ok := v.(*map[string]interface{}); ok {
34 vmap := *m
35 tmap := tree.ToMap()
36 for k, v := range tmap {
37 vmap[k] = v
38 }
39
40 return nil
33 tmap := tree.ToMap()
34 for key, value := range tmap {
35 v[key] = value
4136 }
4237
43 return tree.Unmarshal(v)
38 return nil
4439 }
88 return yaml.Marshal(v)
99 }
1010
11 func (Codec) Decode(b []byte, v interface{}) error {
12 return yaml.Unmarshal(b, v)
11 func (Codec) Decode(b []byte, v map[string]interface{}) error {
12 return yaml.Unmarshal(b, &v)
1313 }
16341634
16351635 switch format := strings.ToLower(v.getConfigType()); format {
16361636 case "yaml", "yml", "json", "toml", "hcl", "tfvars":
1637 err := decoderRegistry.Decode(format, buf.Bytes(), &c)
1637 err := decoderRegistry.Decode(format, buf.Bytes(), c)
16381638 if err != nil {
16391639 return ConfigParseError{err}
16401640 }