92 lines
1.8 KiB
Go
92 lines
1.8 KiB
Go
package dasel
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
|
|
dasel "github.com/tomwright/dasel/v3"
|
|
"github.com/tomwright/dasel/v3/model"
|
|
"github.com/tomwright/dasel/v3/parsing"
|
|
"gitoa.ru/go-4devs/config"
|
|
"gitoa.ru/go-4devs/config/value"
|
|
)
|
|
|
|
var _ config.Provider = Provider{} //nolint:exhaustruct
|
|
|
|
const Name = "dasel"
|
|
|
|
type Option func(*Provider)
|
|
|
|
func WithName(in string) Option {
|
|
return func(p *Provider) {
|
|
p.name = in
|
|
}
|
|
}
|
|
|
|
func New(in []byte, format parsing.Format, opts ...Option) (Provider, error) {
|
|
reader, err := format.NewReader(parsing.DefaultReaderOptions())
|
|
if err != nil {
|
|
return Provider{}, fmt.Errorf("%w:%w", config.ErrInitFactory, err)
|
|
}
|
|
|
|
data, verr := reader.Read(in)
|
|
if verr != nil {
|
|
return Provider{}, fmt.Errorf("%w:%w", config.ErrInitFactory, verr)
|
|
}
|
|
|
|
prov := Provider{
|
|
data: data,
|
|
key: func(path ...string) string {
|
|
return strings.Join(path, ".")
|
|
},
|
|
name: Name,
|
|
}
|
|
|
|
for _, opt := range opts {
|
|
opt(&prov)
|
|
}
|
|
|
|
return prov, nil
|
|
}
|
|
|
|
type Provider struct {
|
|
data *model.Value
|
|
key func(path ...string) string
|
|
name string
|
|
}
|
|
|
|
func (p Provider) Value(ctx context.Context, path ...string) (config.Value, error) {
|
|
selector := p.key(path...)
|
|
|
|
data, cnt, err := dasel.Query(ctx, p.data, selector)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("query: %w:%w", config.ErrInvalidValue, err)
|
|
}
|
|
|
|
if cnt > 1 {
|
|
return nil, fmt.Errorf("count: %v:%w", cnt, config.ErrToManyArgs)
|
|
}
|
|
|
|
if cnt == 0 {
|
|
return value.EmptyValue(), nil
|
|
}
|
|
|
|
val, verr := data[0].GoValue()
|
|
if verr != nil {
|
|
return nil, fmt.Errorf("go value: %w:%w", config.ErrInvalidValue, verr)
|
|
}
|
|
|
|
res, merr := json.Marshal(val)
|
|
if merr != nil {
|
|
return nil, fmt.Errorf("marshal: %w:%w", config.ErrInvalidValue, merr)
|
|
}
|
|
|
|
return value.JBytes(res), nil
|
|
}
|
|
|
|
func (p Provider) Name() string {
|
|
return p.name
|
|
}
|