Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
2a548634fd | |||
598dddc476 | |||
887b48f1e7 | |||
6e55d07636 |
@@ -221,5 +221,8 @@ func (n *noopClient) Publish(ctx context.Context, p Message, opts ...PublishOpti
|
||||
return n.opts.Broker.Publish(ctx, topic, &broker.Message{
|
||||
Header: md,
|
||||
Body: body,
|
||||
}, broker.PublishContext(options.Context))
|
||||
},
|
||||
broker.PublishContext(options.Context),
|
||||
broker.PublishBodyOnly(options.BodyOnly),
|
||||
)
|
||||
}
|
||||
|
@@ -20,25 +20,27 @@ var (
|
||||
|
||||
// Config is an interface abstraction for dynamic configuration
|
||||
type Config interface {
|
||||
// Name returns name of config
|
||||
Name() string
|
||||
// Init the config
|
||||
Init(opts ...Option) error
|
||||
// Options in the config
|
||||
Options() Options
|
||||
// Load config from sources
|
||||
Load(context.Context) error
|
||||
Load(context.Context, ...LoadOption) error
|
||||
// Save config to sources
|
||||
Save(context.Context) error
|
||||
Save(context.Context, ...SaveOption) error
|
||||
// Watch a value for changes
|
||||
// Watch(interface{}) (Watcher, error)
|
||||
//Watch(context.Context) (Watcher, error)
|
||||
// String returns config type name
|
||||
String() string
|
||||
}
|
||||
|
||||
// Watcher is the config watcher
|
||||
// type Watcher interface {
|
||||
// Next() (, error)
|
||||
// Stop() error
|
||||
// }
|
||||
type Watcher interface {
|
||||
// Next() (, error)
|
||||
Stop() error
|
||||
}
|
||||
|
||||
// Load loads config from config sources
|
||||
func Load(ctx context.Context, cs ...Config) error {
|
||||
|
@@ -25,18 +25,27 @@ func (c *defaultConfig) Init(opts ...Option) error {
|
||||
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 {
|
||||
if err := fn(ctx, c); err != nil && !c.opts.AllowFail {
|
||||
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)
|
||||
if err == nil {
|
||||
valueOf := reflect.ValueOf(src)
|
||||
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
|
||||
}
|
||||
|
||||
func (c *defaultConfig) Save(ctx context.Context) error {
|
||||
func (c *defaultConfig) Save(ctx context.Context, opts ...SaveOption) error {
|
||||
for _, fn := range c.opts.BeforeSave {
|
||||
if err := fn(ctx, c); err != nil && !c.opts.AllowFail {
|
||||
return err
|
||||
|
@@ -57,6 +57,52 @@ func NewOptions(opts ...Option) 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
|
||||
func AllowFail(b bool) Option {
|
||||
return func(o *Options) {
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ErrInvalidParam specifies invalid url query params
|
||||
@@ -14,6 +15,13 @@ var ErrInvalidParam = errors.New("invalid url query param provided")
|
||||
|
||||
var bracketSplitter = regexp.MustCompile(`\[|\]`)
|
||||
|
||||
var timeKind = reflect.TypeOf(time.Time{}).Kind()
|
||||
|
||||
type StructField struct {
|
||||
Field reflect.StructField
|
||||
Value reflect.Value
|
||||
}
|
||||
|
||||
func StructFieldByTag(src interface{}, tkey string, tval string) (interface{}, error) {
|
||||
sv := reflect.ValueOf(src)
|
||||
if sv.Kind() == reflect.Ptr {
|
||||
@@ -98,8 +106,8 @@ func StructFieldByName(src interface{}, tkey string) (interface{}, error) {
|
||||
}
|
||||
|
||||
// StructFields returns slice of struct fields
|
||||
func StructFields(src interface{}) ([]reflect.StructField, error) {
|
||||
var fields []reflect.StructField
|
||||
func StructFields(src interface{}) ([]StructField, error) {
|
||||
var fields []StructField
|
||||
|
||||
sv := reflect.ValueOf(src)
|
||||
if sv.Kind() == reflect.Ptr {
|
||||
@@ -116,14 +124,17 @@ func StructFields(src interface{}) ([]reflect.StructField, error) {
|
||||
if !val.CanSet() || len(fld.PkgPath) != 0 {
|
||||
continue
|
||||
}
|
||||
if val.Kind() == reflect.Struct {
|
||||
switch val.Kind() {
|
||||
case timeKind:
|
||||
fields = append(fields, StructField{Field: fld, Value: val})
|
||||
case reflect.Struct:
|
||||
infields, err := StructFields(val.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fields = append(fields, infields...)
|
||||
} else {
|
||||
fields = append(fields, fld)
|
||||
default:
|
||||
fields = append(fields, StructField{Field: fld, Value: val})
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user