mirror of https://github.com/spf13/viper.git
feat(encoding): add default codec registry
Signed-off-by: Mark Sagi-Kazar <mark.sagikazar@gmail.com>
This commit is contained in:
parent
29a215ca4e
commit
15ad72deb2
84
encoding.go
84
encoding.go
|
@ -1,6 +1,9 @@
|
||||||
package viper
|
package viper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/spf13/viper/internal/encoding/dotenv"
|
"github.com/spf13/viper/internal/encoding/dotenv"
|
||||||
"github.com/spf13/viper/internal/encoding/hcl"
|
"github.com/spf13/viper/internal/encoding/hcl"
|
||||||
"github.com/spf13/viper/internal/encoding/ini"
|
"github.com/spf13/viper/internal/encoding/ini"
|
||||||
|
@ -137,3 +140,84 @@ func (r codecRegistry) codec(format string) (Codec, bool) {
|
||||||
|
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DefaultCodecRegistry
|
||||||
|
type DefaultCodecRegistry struct {
|
||||||
|
codecs map[string]Codec
|
||||||
|
|
||||||
|
mu sync.RWMutex
|
||||||
|
once sync.Once
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCodecRegistry returns a new [CodecRegistry], ready to accept custom [Codec]s.
|
||||||
|
func NewCodecRegistry() *DefaultCodecRegistry {
|
||||||
|
r := &DefaultCodecRegistry{}
|
||||||
|
|
||||||
|
r.init()
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *DefaultCodecRegistry) init() {
|
||||||
|
r.once.Do(func() {
|
||||||
|
r.codecs = map[string]Codec{}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterCodec registers a custom [Codec].
|
||||||
|
func (r *DefaultCodecRegistry) RegisterCodec(format string, codec Codec) error {
|
||||||
|
r.init()
|
||||||
|
|
||||||
|
r.mu.Lock()
|
||||||
|
defer r.mu.Unlock()
|
||||||
|
|
||||||
|
r.codecs[strings.ToLower(format)] = codec
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *DefaultCodecRegistry) Encoder(format string) (Encoder, error) {
|
||||||
|
encoder, ok := r.codec(format)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrEncoderNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
return encoder, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *DefaultCodecRegistry) Decoder(format string) (Decoder, error) {
|
||||||
|
decoder, ok := r.codec(format)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrDecoderNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
return decoder, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *DefaultCodecRegistry) codec(format string) (Codec, bool) {
|
||||||
|
r.mu.Lock()
|
||||||
|
defer r.mu.Unlock()
|
||||||
|
|
||||||
|
if r.codecs != nil {
|
||||||
|
codec, ok := r.codecs[format]
|
||||||
|
if ok {
|
||||||
|
return codec, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch format {
|
||||||
|
case "yaml", "yml":
|
||||||
|
return yaml.Codec{}, true
|
||||||
|
|
||||||
|
case "json":
|
||||||
|
return json.Codec{}, true
|
||||||
|
|
||||||
|
case "toml":
|
||||||
|
return toml.Codec{}, true
|
||||||
|
|
||||||
|
case "dotenv", "env":
|
||||||
|
return &dotenv.Codec{}, true
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package viper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
type codec struct{}
|
||||||
|
|
||||||
|
func (codec) Encode(_ map[string]any) ([]byte, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec) Decode(_ []byte, _ map[string]any) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDefaultCodecRegistry(t *testing.T) {
|
||||||
|
t.Run("OK", func(t *testing.T) {
|
||||||
|
registry := NewCodecRegistry()
|
||||||
|
|
||||||
|
c := codec{}
|
||||||
|
|
||||||
|
err := registry.RegisterCodec("myformat", c)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
encoder, err := registry.Encoder("myformat")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, c, encoder)
|
||||||
|
|
||||||
|
decoder, err := registry.Decoder("myformat")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, c, decoder)
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue