|
|
@ -6,6 +6,7 @@ import ( |
|
|
|
"encoding/json" |
|
|
|
"encoding/json" |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
"strings" |
|
|
|
"strings" |
|
|
|
|
|
|
|
"sync" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/imdario/mergo" |
|
|
|
"github.com/imdario/mergo" |
|
|
|
"google.golang.org/protobuf/encoding/protojson" |
|
|
|
"google.golang.org/protobuf/encoding/protojson" |
|
|
@ -23,17 +24,21 @@ type Reader interface { |
|
|
|
type reader struct { |
|
|
|
type reader struct { |
|
|
|
opts options |
|
|
|
opts options |
|
|
|
values map[string]interface{} |
|
|
|
values map[string]interface{} |
|
|
|
|
|
|
|
lock sync.Mutex |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func newReader(opts options) Reader { |
|
|
|
func newReader(opts options) Reader { |
|
|
|
return &reader{ |
|
|
|
return &reader{ |
|
|
|
opts: opts, |
|
|
|
opts: opts, |
|
|
|
values: make(map[string]interface{}), |
|
|
|
values: make(map[string]interface{}), |
|
|
|
|
|
|
|
lock: sync.Mutex{}, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (r *reader) Merge(kvs ...*KeyValue) error { |
|
|
|
func (r *reader) Merge(kvs ...*KeyValue) error { |
|
|
|
|
|
|
|
r.lock.Lock() |
|
|
|
merged, err := cloneMap(r.values) |
|
|
|
merged, err := cloneMap(r.values) |
|
|
|
|
|
|
|
r.lock.Unlock() |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
@ -46,19 +51,27 @@ func (r *reader) Merge(kvs ...*KeyValue) error { |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
r.lock.Lock() |
|
|
|
r.values = merged |
|
|
|
r.values = merged |
|
|
|
|
|
|
|
r.lock.Unlock() |
|
|
|
return nil |
|
|
|
return nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (r *reader) Value(path string) (Value, bool) { |
|
|
|
func (r *reader) Value(path string) (Value, bool) { |
|
|
|
|
|
|
|
r.lock.Lock() |
|
|
|
|
|
|
|
defer r.lock.Unlock() |
|
|
|
return readValue(r.values, path) |
|
|
|
return readValue(r.values, path) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (r *reader) Source() ([]byte, error) { |
|
|
|
func (r *reader) Source() ([]byte, error) { |
|
|
|
|
|
|
|
r.lock.Lock() |
|
|
|
|
|
|
|
defer r.lock.Unlock() |
|
|
|
return marshalJSON(convertMap(r.values)) |
|
|
|
return marshalJSON(convertMap(r.values)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (r *reader) Resolve() error { |
|
|
|
func (r *reader) Resolve() error { |
|
|
|
|
|
|
|
r.lock.Lock() |
|
|
|
|
|
|
|
defer r.lock.Unlock() |
|
|
|
return r.opts.resolver(r.values) |
|
|
|
return r.opts.resolver(r.values) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|