From a842b8f61840c754255435f3c7b131ca89080c78 Mon Sep 17 00:00:00 2001 From: Mark Sagi-Kazar Date: Fri, 8 Nov 2019 14:23:20 +0100 Subject: [PATCH] Replace SetKeyDelimiter with functional options --- README.md | 3 +-- viper.go | 42 +++++++++++++++++++++++++++++++++--------- viper_test.go | 5 ++--- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index f211b06..857588a 100644 --- a/README.md +++ b/README.md @@ -667,8 +667,7 @@ If you want to unmarshal configuration where the keys themselves contain dot (th you have to change the delimiter: ```go -v := viper.New() -v.SetKeyDelimiter("::") +v := viper.NewWithOptions(viper.KeyDelimiter("::")) v.SetDefault("chart::values", map[string]interface{}{ "ingress": map[string]interface{}{ diff --git a/viper.go b/viper.go index 0e3eeaf..dcfd2b0 100644 --- a/viper.go +++ b/viper.go @@ -236,6 +236,39 @@ func New() *Viper { return v } +// Option configures Viper using the functional options paradigm popularized by Rob Pike and Dave Cheney. +// If you're unfamiliar with this style, +// see https://commandcenter.blogspot.com/2014/01/self-referential-functions-and-design.html and +// https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis. +type Option interface { + apply(v *Viper) +} + +type optionFunc func(v *Viper) + +func (fn optionFunc) apply(v *Viper) { + fn(v) +} + +// KeyDelimiter sets the delimiter used for determining key parts. +// By default it's value is ".". +func KeyDelimiter(d string) Option { + return optionFunc(func(v *Viper) { + v.keyDelim = d + }) +} + +// NewWithOptions creates a new Viper instance. +func NewWithOptions(opts ...Option) *Viper { + v := New() + + for _, opt := range opts { + opt.apply(v) + } + + return v +} + // Reset is intended for testing, will reset all to default settings. // In the public interface for the viper package so applications // can use it in their testing as well. @@ -245,15 +278,6 @@ func Reset() { SupportedRemoteProviders = []string{"etcd", "consul"} } -// SetKeyDelimiter sets the delimiter used for determining key parts. -// By default it's value is ".". -func SetKeyDelimiter(keyDelim string) { v.SetKeyDelimiter(keyDelim) } -func (v *Viper) SetKeyDelimiter(keyDelim string) { - if keyDelim != "" { - v.keyDelim = keyDelim - } -} - type defaultRemoteProvider struct { provider string endpoint string diff --git a/viper_test.go b/viper_test.go index baf0998..9f4dff3 100644 --- a/viper_test.go +++ b/viper_test.go @@ -2029,9 +2029,8 @@ emails: active: true `) -func TestSetKeyDelimiter(t *testing.T) { - v := New() - v.SetKeyDelimiter("::") +func TestKeyDelimiter(t *testing.T) { + v := NewWithOptions(KeyDelimiter("::")) v.SetConfigType("yaml") r := strings.NewReader(string(yamlExampleWithDot))