add provider processor
All checks were successful
Go Action / goaction (pull_request) Successful in 1m9s
All checks were successful
Go Action / goaction (pull_request) Successful in 1m9s
This commit is contained in:
101
provider/handler/processor.go
Normal file
101
provider/handler/processor.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"gitoa.ru/go-4devs/config"
|
||||
"gitoa.ru/go-4devs/config/key"
|
||||
"gitoa.ru/go-4devs/config/param"
|
||||
)
|
||||
|
||||
type pkey uint8
|
||||
|
||||
const (
|
||||
processorKey pkey = iota + 1
|
||||
)
|
||||
|
||||
func Process(fn config.Processor) param.Option {
|
||||
return func(p param.Params) param.Params {
|
||||
return param.With(p, processorKey, fn)
|
||||
}
|
||||
}
|
||||
|
||||
func getProcess(in param.Params) (config.Processor, bool) {
|
||||
p, ok := in.Param(processorKey)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
data, tok := p.(config.Processor)
|
||||
|
||||
return data, tok
|
||||
}
|
||||
|
||||
func Processor(parent config.Provider) *ProcessHandler {
|
||||
handler := &ProcessHandler{
|
||||
Provider: parent,
|
||||
name: "process:" + parent.Name(),
|
||||
idx: key.Map{},
|
||||
process: nil,
|
||||
}
|
||||
|
||||
return handler
|
||||
}
|
||||
|
||||
type ProcessHandler struct {
|
||||
config.Provider
|
||||
|
||||
idx key.Map
|
||||
process []config.Processor
|
||||
name string
|
||||
}
|
||||
|
||||
func (p *ProcessHandler) Name() string {
|
||||
return p.name
|
||||
}
|
||||
|
||||
func (p *ProcessHandler) Bind(ctx context.Context, vars config.Variables) error {
|
||||
for _, one := range vars.Variables() {
|
||||
process, ok := getProcess(one)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
p.idx.Add(len(p.process), one.Key())
|
||||
p.process = append(p.process, process)
|
||||
}
|
||||
|
||||
log.Print(p.idx.Index([]string{"group", "int"}))
|
||||
|
||||
if bind, bok := p.Provider.(config.BindProvider); bok {
|
||||
berr := bind.Bind(ctx, vars)
|
||||
if berr != nil {
|
||||
return fmt.Errorf("%w", berr)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ProcessHandler) Value(ctx context.Context, key ...string) (config.Value, error) {
|
||||
pval, perr := p.Provider.Value(ctx, key...)
|
||||
if perr != nil {
|
||||
return nil, fmt.Errorf("%w", perr)
|
||||
}
|
||||
|
||||
idx, iok := p.idx.Index(key)
|
||||
if !iok {
|
||||
return pval, nil
|
||||
}
|
||||
|
||||
prov := p.process[idx]
|
||||
|
||||
val, err := prov.Process(ctx, pval)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("process[%v]:%w", p.Name(), err)
|
||||
}
|
||||
|
||||
return val, nil
|
||||
}
|
||||
87
provider/handler/processor_test.go
Normal file
87
provider/handler/processor_test.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package handler_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"gitoa.ru/go-4devs/config"
|
||||
"gitoa.ru/go-4devs/config/definition/group"
|
||||
"gitoa.ru/go-4devs/config/definition/option"
|
||||
"gitoa.ru/go-4devs/config/definition/proto"
|
||||
"gitoa.ru/go-4devs/config/param"
|
||||
"gitoa.ru/go-4devs/config/processor/csv"
|
||||
"gitoa.ru/go-4devs/config/provider/handler"
|
||||
"gitoa.ru/go-4devs/config/provider/memory"
|
||||
"gitoa.ru/go-4devs/config/test/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testKey = []string{"test"}
|
||||
testBool = []string{"group", "service", "bool"}
|
||||
testInt = []string{"group", "int"}
|
||||
)
|
||||
|
||||
func TestProcessor(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
prov := handler.Processor(&memory.Default{})
|
||||
require.NoError(t, prov.Bind(ctx, testVariables(t)))
|
||||
|
||||
tval, terr := prov.Value(ctx, testKey...)
|
||||
require.NoError(t, terr)
|
||||
|
||||
var tdata []string
|
||||
|
||||
require.NoError(t, tval.Unmarshal(&tdata))
|
||||
require.Equal(t, []string{"test1", "test2"}, tdata)
|
||||
|
||||
bval, berr := prov.Value(ctx, testBool...)
|
||||
require.NoError(t, berr)
|
||||
|
||||
var bdata []bool
|
||||
|
||||
require.NoError(t, bval.Unmarshal(&bdata))
|
||||
require.Equal(t, []bool{true, false, true}, bdata)
|
||||
|
||||
ival, ierr := prov.Value(ctx, testInt...)
|
||||
require.NoError(t, ierr)
|
||||
|
||||
var idata []int
|
||||
|
||||
require.NoError(t, ival.Unmarshal(&idata))
|
||||
require.Equal(t, []int{42, 0, 1}, idata)
|
||||
}
|
||||
|
||||
func testVariables(t *testing.T) config.Variables {
|
||||
t.Helper()
|
||||
|
||||
vars := config.NewVars(
|
||||
option.String("test", "test",
|
||||
option.Slice,
|
||||
option.Default("test1,test2"),
|
||||
handler.Process(config.ProcessFunc(csv.Csv)),
|
||||
),
|
||||
group.New("group", "group",
|
||||
proto.New("proto", "proto",
|
||||
option.Bool("bool", "bool",
|
||||
option.Slice,
|
||||
option.Default("true|false|true"),
|
||||
handler.Process(config.ProcessFunc(func(ctx context.Context, in config.Value, _ ...param.Option) (config.Value, error) {
|
||||
return csv.Csv(ctx, in, csv.WithBool, csv.WithDelimiter('|'))
|
||||
})),
|
||||
),
|
||||
),
|
||||
option.Int("int", "int",
|
||||
option.Slice,
|
||||
option.Default("42,0,1"),
|
||||
handler.Process(config.ProcessFunc(func(ctx context.Context, in config.Value, _ ...param.Option) (config.Value, error) {
|
||||
return csv.Csv(ctx, in, csv.WithInt)
|
||||
})),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
return vars
|
||||
}
|
||||
Reference in New Issue
Block a user