move implementations to external repos (#17)

Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
2020-08-25 13:44:41 +03:00
committed by GitHub
parent c4a303190a
commit 0f4b1435d9
238 changed files with 151 additions and 37364 deletions

View File

@@ -1,83 +0,0 @@
package json
import (
"errors"
"time"
"github.com/imdario/mergo"
"github.com/unistack-org/micro/v3/config/encoder"
"github.com/unistack-org/micro/v3/config/encoder/json"
"github.com/unistack-org/micro/v3/config/reader"
"github.com/unistack-org/micro/v3/config/source"
)
type jsonReader struct {
opts reader.Options
json encoder.Encoder
}
func (j *jsonReader) Merge(changes ...*source.ChangeSet) (*source.ChangeSet, error) {
var merged map[string]interface{}
for _, m := range changes {
if m == nil {
continue
}
if len(m.Data) == 0 {
continue
}
codec, ok := j.opts.Encoding[m.Format]
if !ok {
// fallback
codec = j.json
}
var data map[string]interface{}
if err := codec.Decode(m.Data, &data); err != nil {
return nil, err
}
if err := mergo.Map(&merged, data, mergo.WithOverride); err != nil {
return nil, err
}
}
b, err := j.json.Encode(merged)
if err != nil {
return nil, err
}
cs := &source.ChangeSet{
Timestamp: time.Now(),
Data: b,
Source: "json",
Format: j.json.String(),
}
cs.Checksum = cs.Sum()
return cs, nil
}
func (j *jsonReader) Values(ch *source.ChangeSet) (reader.Values, error) {
if ch == nil {
return nil, errors.New("changeset is nil")
}
if ch.Format != "json" {
return nil, errors.New("unsupported format")
}
return newValues(ch, j.opts)
}
func (j *jsonReader) String() string {
return "json"
}
// NewReader creates a json reader
func NewReader(opts ...reader.Option) reader.Reader {
options := reader.NewOptions(opts...)
return &jsonReader{
json: json.NewEncoder(),
opts: options,
}
}

View File

@@ -1,79 +0,0 @@
package json
import (
"testing"
"github.com/unistack-org/micro/v3/config/reader"
"github.com/unistack-org/micro/v3/config/source"
)
func TestReader(t *testing.T) {
data := []byte(`{"foo": "bar", "baz": {"bar": "cat"}}`)
testData := []struct {
path []string
value string
}{
{
[]string{"foo"},
"bar",
},
{
[]string{"baz", "bar"},
"cat",
},
}
values := newTestValues(t, data)
for _, test := range testData {
if v := values.Get(test.path...).String(""); v != test.value {
t.Fatalf("Expected %s got %s for path %v", test.value, v, test.path)
}
}
}
func TestDisableReplaceEnvVars(t *testing.T) {
data := []byte(`{"foo": "bar", "baz": {"bar": "test/${test}"}}`)
tests := []struct {
path []string
value string
opts []reader.Option
}{
{
[]string{"baz", "bar"},
"test/",
nil,
},
{
[]string{"baz", "bar"},
"test/${test}",
[]reader.Option{reader.WithDisableReplaceEnvVars()},
},
}
for _, test := range tests {
values := newTestValues(t, data, test.opts...)
if v := values.Get(test.path...).String(""); v != test.value {
t.Fatalf("Expected %s got %s for path %v", test.value, v, test.path)
}
}
}
func newTestValues(t *testing.T, data []byte, opts ...reader.Option) reader.Values {
r := NewReader(opts...)
c, err := r.Merge(&source.ChangeSet{Data: data}, &source.ChangeSet{})
if err != nil {
t.Fatal(err)
}
values, err := r.Values(c)
if err != nil {
t.Fatal(err)
}
return values
}

View File

@@ -1,205 +0,0 @@
package json
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
simple "github.com/bitly/go-simplejson"
"github.com/unistack-org/micro/v3/config/reader"
"github.com/unistack-org/micro/v3/config/source"
)
type jsonValues struct {
ch *source.ChangeSet
sj *simple.Json
}
type jsonValue struct {
*simple.Json
}
func newValues(ch *source.ChangeSet, opts reader.Options) (reader.Values, error) {
sj := simple.New()
data := ch.Data
if !opts.DisableReplaceEnvVars {
data, _ = reader.ReplaceEnvVars(ch.Data)
}
if err := sj.UnmarshalJSON(data); err != nil {
sj.SetPath(nil, string(ch.Data))
}
return &jsonValues{ch, sj}, nil
}
func (j *jsonValues) Get(path ...string) reader.Value {
return &jsonValue{j.sj.GetPath(path...)}
}
func (j *jsonValues) Del(path ...string) {
// delete the tree?
if len(path) == 0 {
j.sj = simple.New()
return
}
if len(path) == 1 {
j.sj.Del(path[0])
return
}
vals := j.sj.GetPath(path[:len(path)-1]...)
vals.Del(path[len(path)-1])
j.sj.SetPath(path[:len(path)-1], vals.Interface())
}
func (j *jsonValues) Set(val interface{}, path ...string) {
j.sj.SetPath(path, val)
}
func (j *jsonValues) Bytes() []byte {
b, _ := j.sj.MarshalJSON()
return b
}
func (j *jsonValues) Map() map[string]interface{} {
m, _ := j.sj.Map()
return m
}
func (j *jsonValues) Scan(v interface{}) error {
b, err := j.sj.MarshalJSON()
if err != nil {
return err
}
return json.Unmarshal(b, v)
}
func (j *jsonValues) String() string {
return "json"
}
func (j *jsonValue) Bool(def bool) bool {
b, err := j.Json.Bool()
if err == nil {
return b
}
str, ok := j.Interface().(string)
if !ok {
return def
}
b, err = strconv.ParseBool(str)
if err != nil {
return def
}
return b
}
func (j *jsonValue) Int(def int) int {
i, err := j.Json.Int()
if err == nil {
return i
}
str, ok := j.Interface().(string)
if !ok {
return def
}
i, err = strconv.Atoi(str)
if err != nil {
return def
}
return i
}
func (j *jsonValue) String(def string) string {
return j.Json.MustString(def)
}
func (j *jsonValue) Float64(def float64) float64 {
f, err := j.Json.Float64()
if err == nil {
return f
}
str, ok := j.Interface().(string)
if !ok {
return def
}
f, err = strconv.ParseFloat(str, 64)
if err != nil {
return def
}
return f
}
func (j *jsonValue) Duration(def time.Duration) time.Duration {
v, err := j.Json.String()
if err != nil {
return def
}
value, err := time.ParseDuration(v)
if err != nil {
return def
}
return value
}
func (j *jsonValue) StringSlice(def []string) []string {
v, err := j.Json.String()
if err == nil {
sl := strings.Split(v, ",")
if len(sl) > 1 {
return sl
}
}
return j.Json.MustStringArray(def)
}
func (j *jsonValue) StringMap(def map[string]string) map[string]string {
m, err := j.Json.Map()
if err != nil {
return def
}
res := map[string]string{}
for k, v := range m {
res[k] = fmt.Sprintf("%v", v)
}
return res
}
func (j *jsonValue) Scan(v interface{}) error {
b, err := j.Json.MarshalJSON()
if err != nil {
return err
}
return json.Unmarshal(b, v)
}
func (j *jsonValue) Bytes() []byte {
b, err := j.Json.Bytes()
if err != nil {
// try return marshalled
b, err = j.Json.MarshalJSON()
if err != nil {
return []byte{}
}
return b
}
return b
}

View File

@@ -1,86 +0,0 @@
package json
import (
"reflect"
"testing"
"github.com/unistack-org/micro/v3/config/reader"
"github.com/unistack-org/micro/v3/config/source"
)
func TestValues(t *testing.T) {
emptyStr := ""
testData := []struct {
csdata []byte
path []string
accepter interface{}
value interface{}
}{
{
[]byte(`{"foo": "bar", "baz": {"bar": "cat"}}`),
[]string{"foo"},
emptyStr,
"bar",
},
{
[]byte(`{"foo": "bar", "baz": {"bar": "cat"}}`),
[]string{"baz", "bar"},
emptyStr,
"cat",
},
}
for idx, test := range testData {
values, err := newValues(&source.ChangeSet{
Data: test.csdata,
}, reader.Options{})
if err != nil {
t.Fatal(err)
}
err = values.Get(test.path...).Scan(&test.accepter)
if err != nil {
t.Fatal(err)
}
if test.accepter != test.value {
t.Fatalf("No.%d Expected %v got %v for path %v", idx, test.value, test.accepter, test.path)
}
}
}
func TestStructArray(t *testing.T) {
type T struct {
Foo string
}
emptyTSlice := []T{}
testData := []struct {
csdata []byte
accepter []T
value []T
}{
{
[]byte(`[{"foo": "bar"}]`),
emptyTSlice,
[]T{{Foo: "bar"}},
},
}
for idx, test := range testData {
values, err := newValues(&source.ChangeSet{
Data: test.csdata,
}, reader.Options{})
if err != nil {
t.Fatal(err)
}
err = values.Get().Scan(&test.accepter)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(test.accepter, test.value) {
t.Fatalf("No.%d Expected %v got %v", idx, test.value, test.accepter)
}
}
}