config: add Save/Load options
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
parent
598dddc476
commit
2a548634fd
@ -20,25 +20,27 @@ var (
|
|||||||
|
|
||||||
// Config is an interface abstraction for dynamic configuration
|
// Config is an interface abstraction for dynamic configuration
|
||||||
type Config interface {
|
type Config interface {
|
||||||
|
// Name returns name of config
|
||||||
Name() string
|
Name() string
|
||||||
// Init the config
|
// Init the config
|
||||||
Init(opts ...Option) error
|
Init(opts ...Option) error
|
||||||
// Options in the config
|
// Options in the config
|
||||||
Options() Options
|
Options() Options
|
||||||
// Load config from sources
|
// Load config from sources
|
||||||
Load(context.Context) error
|
Load(context.Context, ...LoadOption) error
|
||||||
// Save config to sources
|
// Save config to sources
|
||||||
Save(context.Context) error
|
Save(context.Context, ...SaveOption) error
|
||||||
// Watch a value for changes
|
// Watch a value for changes
|
||||||
// Watch(interface{}) (Watcher, error)
|
//Watch(context.Context) (Watcher, error)
|
||||||
|
// String returns config type name
|
||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watcher is the config watcher
|
// Watcher is the config watcher
|
||||||
// type Watcher interface {
|
type Watcher interface {
|
||||||
// Next() (, error)
|
// Next() (, error)
|
||||||
// Stop() error
|
Stop() error
|
||||||
// }
|
}
|
||||||
|
|
||||||
// Load loads config from config sources
|
// Load loads config from config sources
|
||||||
func Load(ctx context.Context, cs ...Config) error {
|
func Load(ctx context.Context, cs ...Config) error {
|
||||||
|
@ -25,18 +25,27 @@ func (c *defaultConfig) Init(opts ...Option) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *defaultConfig) Load(ctx context.Context) error {
|
func (c *defaultConfig) Load(ctx context.Context, opts ...LoadOption) error {
|
||||||
for _, fn := range c.opts.BeforeLoad {
|
for _, fn := range c.opts.BeforeLoad {
|
||||||
if err := fn(ctx, c); err != nil && !c.opts.AllowFail {
|
if err := fn(ctx, c); err != nil && !c.opts.AllowFail {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options := NewLoadOptions(opts...)
|
||||||
|
mopts := []func(*mergo.Config){mergo.WithTypeCheck}
|
||||||
|
if options.Override {
|
||||||
|
mopts = append(mopts, mergo.WithOverride)
|
||||||
|
}
|
||||||
|
if options.Append {
|
||||||
|
mopts = append(mopts, mergo.WithAppendSlice)
|
||||||
|
}
|
||||||
|
|
||||||
src, err := rutil.Zero(c.opts.Struct)
|
src, err := rutil.Zero(c.opts.Struct)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
valueOf := reflect.ValueOf(src)
|
valueOf := reflect.ValueOf(src)
|
||||||
if err = c.fillValues(valueOf); err == nil {
|
if err = c.fillValues(valueOf); err == nil {
|
||||||
err = mergo.Merge(c.opts.Struct, src, mergo.WithOverride, mergo.WithTypeCheck, mergo.WithAppendSlice)
|
err = mergo.Merge(c.opts.Struct, src, mopts...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +241,7 @@ func (c *defaultConfig) fillValues(valueOf reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *defaultConfig) Save(ctx context.Context) error {
|
func (c *defaultConfig) Save(ctx context.Context, opts ...SaveOption) error {
|
||||||
for _, fn := range c.opts.BeforeSave {
|
for _, fn := range c.opts.BeforeSave {
|
||||||
if err := fn(ctx, c); err != nil && !c.opts.AllowFail {
|
if err := fn(ctx, c); err != nil && !c.opts.AllowFail {
|
||||||
return err
|
return err
|
||||||
|
@ -57,6 +57,52 @@ func NewOptions(opts ...Option) Options {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadOption function signature
|
||||||
|
type LoadOption func(o *LoadOptions)
|
||||||
|
|
||||||
|
// LoadOptions struct
|
||||||
|
type LoadOptions struct {
|
||||||
|
Override bool
|
||||||
|
Append bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLoadOptions(opts ...LoadOption) LoadOptions {
|
||||||
|
options := LoadOptions{}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadOverride override values when load
|
||||||
|
func LoadOverride(b bool) LoadOption {
|
||||||
|
return func(o *LoadOptions) {
|
||||||
|
o.Override = b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadAppend override values when load
|
||||||
|
func LoadAppend(b bool) LoadOption {
|
||||||
|
return func(o *LoadOptions) {
|
||||||
|
o.Append = b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveOption function signature
|
||||||
|
type SaveOption func(o *SaveOptions)
|
||||||
|
|
||||||
|
// SaveOptions struct
|
||||||
|
type SaveOptions struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSaveOptions(opts ...SaveOption) SaveOptions {
|
||||||
|
options := SaveOptions{}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
// AllowFail allows config source to fail
|
// AllowFail allows config source to fail
|
||||||
func AllowFail(b bool) Option {
|
func AllowFail(b bool) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
|
Loading…
Reference in New Issue
Block a user