Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
cristaloleg committed Dec 26, 2023
1 parent 5cfc928 commit a312968
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 40 deletions.
12 changes: 6 additions & 6 deletions aconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
// Loader of user configuration.
type Loader struct {
config Config
dst interface{}
dst any
parser *structParser
fields []*fieldData
fsys fs.FS
Expand Down Expand Up @@ -103,7 +103,7 @@ type Config struct {
// FileDecoder is used to read config from files. See aconfig submodules.
type FileDecoder interface {
Format() string
DecodeFile(filename string) (map[string]interface{}, error)
DecodeFile(filename string) (map[string]any, error)
// Init(fsys fs.FS)
}

Expand All @@ -122,7 +122,7 @@ type Field interface {

// LoaderFor creates a new Loader based on a given configuration structure.
// Supports only non-nil structures.
func LoaderFor(dst interface{}, cfg Config) *Loader {
func LoaderFor(dst any, cfg Config) *Loader {
assertStruct(dst)

l := &Loader{
Expand Down Expand Up @@ -435,7 +435,7 @@ func (l *Loader) loadEnvironment() error {
return l.postEnvCheck(actualEnvs, dupls)
}

func (l *Loader) postEnvCheck(values map[string]interface{}, dupls map[string]struct{}) error {
func (l *Loader) postEnvCheck(values map[string]any, dupls map[string]struct{}) error {
if l.config.AllowUnknownEnvs || l.config.EnvPrefix == "" {
return nil
}
Expand Down Expand Up @@ -473,7 +473,7 @@ func (l *Loader) loadFlags() error {
return l.postFlagCheck(actualFlags, dupls)
}

func (l *Loader) postFlagCheck(values map[string]interface{}, dupls map[string]struct{}) error {
func (l *Loader) postFlagCheck(values map[string]any, dupls map[string]struct{}) error {
if l.config.AllowUnknownFlags || l.config.FlagPrefix == "" {
return nil
}
Expand All @@ -489,7 +489,7 @@ func (l *Loader) postFlagCheck(values map[string]interface{}, dupls map[string]s
}

// TODO(cristaloleg): revisit.
func (l *Loader) setField(field *fieldData, name string, values map[string]interface{}, dupls map[string]struct{}) error {
func (l *Loader) setField(field *fieldData, name string, values map[string]any, dupls map[string]struct{}) error {
if !l.config.AllowDuplicates {
if _, ok := dupls[name]; ok {
return fmt.Errorf("field %q is duplicated", name)
Expand Down
12 changes: 6 additions & 6 deletions aconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ func TestUsage(t *testing.T) {
}

func TestBadDefauts(t *testing.T) {
f := func(cfg interface{}) {
f := func(cfg any) {
t.Helper()

loader := LoaderFor(cfg, Config{
Expand Down Expand Up @@ -1153,7 +1153,7 @@ func TestDontFillFlagsIfDisabled(t *testing.T) {
}

func TestPassBadStructs(t *testing.T) {
f := func(cfg interface{}) {
f := func(cfg any) {
t.Helper()

defer func() {
Expand Down Expand Up @@ -1185,7 +1185,7 @@ func TestBadRequiredTag(t *testing.T) {
Field string `required:"boom"`
}

f := func(cfg interface{}) {
f := func(cfg any) {
t.Helper()

defer func() {
Expand Down Expand Up @@ -1280,7 +1280,7 @@ type structConfig struct {
AA structA `json:"A"`
StructM

MM interface{} `json:"MM"`
MM any `json:"MM"`

P *structP `json:"P"`
}
Expand Down Expand Up @@ -1358,7 +1358,7 @@ var testfile = &fstest.MapFile{Data: []byte(`{
var wantConfig = func() structConfig {
i := int32(42)
j := int64(420)
mInterface := make([]interface{}, 2)
mInterface := make([]any, 2)
for iI, vI := range []string{"q", "w"} {
mInterface[iI] = vI
}
Expand Down Expand Up @@ -1582,7 +1582,7 @@ func failIfErr(tb testing.TB, err error) {
}
}

func mustEqual(tb testing.TB, got, want interface{}) {
func mustEqual(tb testing.TB, got, want any) {
tb.Helper()
if !reflect.DeepEqual(got, want) {
tb.Fatalf("\nhave %+v\nwant %+v", got, want)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module github.com/cristalhq/aconfig

go 1.16
go 1.18

require github.com/mitchellh/mapstructure v1.5.0
51 changes: 24 additions & 27 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import (
)

type structParser struct {
dst interface{}
cfg Config
fields map[string]interface{}
fields map[string]any
flagSet *flag.FlagSet
envNames map[string]struct{}
flagNames map[string]struct{}
Expand All @@ -32,14 +31,13 @@ func newStructParser(cfg Config) *structParser {
type parsedField struct {
name string
namefull string
value interface{}
defaultValue interface{}
value any
defaultValue any
parent *parsedField
childs map[string]interface{}
childs map[string]any
tags map[string]string
hasChilds bool
isRequired bool
isSet bool
}

func (pf *parsedField) String() string {
Expand Down Expand Up @@ -160,13 +158,13 @@ func (sp *structParser) newParseField(parent *parsedField, field reflect.StructF
return pfield, nil
}

func (sp *structParser) parseStruct(x interface{}) error {
func (sp *structParser) parseStruct(x any) error {
value := reflect.ValueOf(x)
if value.Type().Kind() == reflect.Ptr {
value = value.Elem()
}

fields, err := sp.parseStructHelper(nil, value, map[string]interface{}{})
fields, err := sp.parseStructHelper(nil, value, map[string]any{})
if err != nil {
return err
}
Expand All @@ -176,7 +174,7 @@ func (sp *structParser) parseStruct(x interface{}) error {
return nil
}

func (sp *structParser) parseStructHelper(parent *parsedField, structValue reflect.Value, res map[string]interface{}) (map[string]interface{}, error) {
func (sp *structParser) parseStructHelper(parent *parsedField, structValue reflect.Value, res map[string]any) (map[string]any, error) {
count := structValue.NumField()
structType := structValue.Type()

Expand Down Expand Up @@ -232,7 +230,7 @@ func (sp *structParser) parseStructHelper(parent *parsedField, structValue refle
case reflect.Struct:
pfield.hasChilds = true

param := map[string]interface{}{}
param := map[string]any{}
parent := pfield
if field.Anonymous {
pfield.hasChilds = false
Expand All @@ -254,8 +252,8 @@ func (sp *structParser) parseStructHelper(parent *parsedField, structValue refle
if field.Type.Elem().Kind() == reflect.Uint8 {
value = []byte(defaultTagValue)
} else {
values := []interface{}{}
if defaultTagValue != "" && strings.Index(defaultTagValue, ",") == -1 {
values := []any{}
if defaultTagValue != "" && !strings.Contains(defaultTagValue, ",") {
return nil, fmt.Errorf("incorrect default tag value for slice/array: %v", defaultTagValue)
}
for _, val := range strings.Split(defaultTagValue, ",") {
Expand All @@ -266,7 +264,7 @@ func (sp *structParser) parseStructHelper(parent *parsedField, structValue refle
} else {
pfield.hasChilds = true
// TODO: if value is struct - parse
// value = parseSlice(fieldValue, map[string]interface{}{})
// value = parseSlice(fieldValue, map[string]any{})
}

// if !sp.cfg.SkipDefaults {
Expand All @@ -275,9 +273,9 @@ func (sp *structParser) parseStructHelper(parent *parsedField, structValue refle

case reflect.Map:
// if isPrimitive(field.Type.Elem()) {
values := map[string]interface{}{}
values := map[string]any{}
parts := strings.Split(defaultTagValue, ",")
if defaultTagValue != "" && strings.Index(defaultTagValue, ",") == -1 {
if defaultTagValue != "" && !strings.Contains(defaultTagValue, ",") {
return nil, fmt.Errorf("incorrect default tag value for map: %v", defaultTagValue)
}

Expand Down Expand Up @@ -314,7 +312,6 @@ func (sp *structParser) parseStructHelper(parent *parsedField, structValue refle
value = val
}
}

}
}

Expand All @@ -333,7 +330,7 @@ func (sp *structParser) parseStructHelper(parent *parsedField, structValue refle

var fieldType = reflect.TypeOf(&parsedField{})

var hook = mapstructure.DecodeHookFuncType(func(from, to reflect.Type, data interface{}) (interface{}, error) {
var hook = mapstructure.DecodeHookFuncType(func(from, to reflect.Type, data any) (any, error) {
if from != fieldType {
// fmt.Printf("hook: got %T (%+v) when %s\n", i, i, to.String())
return data, nil
Expand All @@ -351,7 +348,7 @@ var hook = mapstructure.DecodeHookFuncType(func(from, to reflect.Type, data inte
return field.value, nil
})

func (sp *structParser) apply(x interface{}) error {
func (sp *structParser) apply(x any) error {
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Result: x,
DecodeHook: hook,
Expand All @@ -367,7 +364,7 @@ func (sp *structParser) apply(x interface{}) error {
return nil
}

func (sp *structParser) applyLevel(tag string, values map[string]interface{}) error {
func (sp *structParser) applyLevel(tag string, values map[string]any) error {
if err := sp.applyLevelHelper2(sp.fields, tag, values); err != nil {
return err
}
Expand All @@ -380,7 +377,7 @@ func (sp *structParser) applyLevel(tag string, values map[string]interface{}) er
return nil
}

func (sp *structParser) applyLevelHelper2(fields map[string]interface{}, tag string, values map[string]interface{}) error {
func (sp *structParser) applyLevelHelper2(fields map[string]any, tag string, values map[string]any) error {
for _, field := range fields {
pfield, ok := field.(*parsedField)
if !ok {
Expand All @@ -397,9 +394,9 @@ func (sp *structParser) applyLevelHelper2(fields map[string]interface{}, tag str
}

switch value := value.(type) {
case map[string]interface{}:
case map[string]any:
if pfield.hasChilds {
pfieldValue, ok := pfield.value.(map[string]interface{})
pfieldValue, ok := pfield.value.(map[string]any)
if !ok {
fmt.Printf("ouch %T (%+v)\n", pfield.value, pfield.value)
continue
Expand All @@ -420,7 +417,7 @@ func (sp *structParser) applyLevelHelper2(fields map[string]interface{}, tag str
return nil
}

func (sp *structParser) applyLevelHelper(fields map[string]interface{}, tag string, values map[string]interface{}) error {
func (sp *structParser) applyLevelHelper(fields map[string]any, tag string, values map[string]any) error {
for _, v := range fields {
field, ok := v.(*parsedField)
if !ok {
Expand All @@ -433,7 +430,7 @@ func (sp *structParser) applyLevelHelper(fields map[string]interface{}, tag stri
if !ok {
continue
}
vval, ok := value.(map[string]interface{})
vval, ok := value.(map[string]any)

// TODO: can be only for leaf nodes?
if !ok {
Expand All @@ -457,7 +454,7 @@ func (sp *structParser) applyLevelHelper(fields map[string]interface{}, tag stri
return nil
}

func (sp *structParser) applyFlat(tag string, values map[string]interface{}) error {
func (sp *structParser) applyFlat(tag string, values map[string]any) error {
allowUnknown := true
prefix := ""

Expand Down Expand Up @@ -489,7 +486,7 @@ func (sp *structParser) applyFlat(tag string, values map[string]interface{}) err
return nil
}

func (sp *structParser) applyFlatHelper(fields map[string]interface{}, tag string, values map[string]interface{}) error {
func (sp *structParser) applyFlatHelper(fields map[string]any, tag string, values map[string]any) error {
for _, field := range fields {
pfield, ok := field.(*parsedField)
if !ok {
Expand All @@ -506,7 +503,7 @@ func (sp *structParser) applyFlatHelper(fields map[string]interface{}, tag strin
if !pfield.hasChilds {
continue
}
if err := sp.applyFlatHelper(pfield.value.(map[string]interface{}), tag, values); err != nil {
if err := sp.applyFlatHelper(pfield.value.(map[string]any), tag, values); err != nil {
return err
}
continue
Expand Down

0 comments on commit a312968

Please sign in to comment.