viper/encoding.go

114 lines
2.9 KiB
Go
Raw Normal View History

package viper
import (
"github.com/spf13/viper/internal/encoding/dotenv"
"github.com/spf13/viper/internal/encoding/hcl"
"github.com/spf13/viper/internal/encoding/ini"
"github.com/spf13/viper/internal/encoding/javaproperties"
"github.com/spf13/viper/internal/encoding/json"
"github.com/spf13/viper/internal/encoding/toml"
"github.com/spf13/viper/internal/encoding/yaml"
)
// Encoder encodes Viper's internal data structures into a byte representation.
// It's primarily used for encoding a map[string]any into a file format.
type Encoder interface {
Encode(v map[string]any) ([]byte, error)
}
// Decoder decodes the contents of a byte slice into Viper's internal data structures.
// It's primarily used for decoding contents of a file into a map[string]any.
type Decoder interface {
Decode(b []byte, v map[string]any) error
}
// Codec combines [Encoder] and [Decoder] interfaces.
type Codec interface {
Encoder
Decoder
}
// EncoderRegistry returns an [Encoder] for a given format.
// The second return value is false if no [Encoder] is registered for the format.
type EncoderRegistry interface {
Encoder(format string) (Encoder, bool)
}
// DecoderRegistry returns an [Decoder] for a given format.
// The second return value is false if no [Decoder] is registered for the format.
type DecoderRegistry interface {
Decoder(format string) (Decoder, bool)
}
// [CodecRegistry] combines [EncoderRegistry] and [DecoderRegistry] interfaces.
type CodecRegistry interface {
EncoderRegistry
DecoderRegistry
}
// WithEncoderRegistry sets a custom [EncoderRegistry].
func WithEncoderRegistry(r EncoderRegistry) Option {
return optionFunc(func(v *Viper) {
v.encoderRegistry2 = r
})
}
// WithDecoderRegistry sets a custom [DecoderRegistry].
func WithDecoderRegistry(r DecoderRegistry) Option {
return optionFunc(func(v *Viper) {
v.decoderRegistry2 = r
})
}
// WithCodecRegistry sets a custom [EncoderRegistry] and [DecoderRegistry].
func WithCodecRegistry(r CodecRegistry) Option {
return optionFunc(func(v *Viper) {
v.encoderRegistry2 = r
v.decoderRegistry2 = r
})
}
type codecRegistry struct {
v *Viper
}
func (r codecRegistry) Encoder(format string) (Encoder, bool) {
return r.codec(format)
}
func (r codecRegistry) Decoder(format string) (Decoder, bool) {
return r.codec(format)
}
func (r codecRegistry) codec(format string) (Codec, bool) {
switch format {
case "yaml", "yml":
return yaml.Codec{}, true
case "json":
return json.Codec{}, true
case "toml":
return toml.Codec{}, true
case "hcl", "tfvars":
return hcl.Codec{}, true
case "ini":
return ini.Codec{
KeyDelimiter: r.v.keyDelim,
LoadOptions: r.v.iniLoadOptions,
}, true
case "properties", "props", "prop": // Note: This breaks writing a properties file.
return &javaproperties.Codec{
KeyDelimiter: v.keyDelim,
}, true
case "dotenv", "env":
return &dotenv.Codec{}, true
}
return nil, false
}