gookit / config

📝 Go configuration manage(load,get,set,export). support JSON, YAML, TOML, Properties, INI, HCL, ENV and Flags. Multi file load, data override merge, parse ENV var. Go应用配置加载管理,支持多种格式,多文件加载,远程文件加载,支持数据合并,解析环境变量名

Home Page:https://pkg.go.dev/github.com/gookit/config/v2

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

mapstructure.DecoderConfig.Squash support config in Options()

RelicOfTesla opened this issue · comments

cfgLoader := config.NewWithOptions("", func(options *config.Options) {
    options.TagName = "json"
    options.Squash  = true
})

type Test1 struct {
    B int `json:"b"`
}
type Test2 struct {
    Test1
    C int `json:"c"`
}
cfg := &Test2{}

cfgLoader.BindStruct("", cfg)
mapConf := &mapstructure.DecoderConfig{
		Metadata: nil,
		Result:   dst,
		TagName:  c.opts.TagName,
                Squash :  c.opts.Squash ,                   // support embedded structs
		// will auto convert string to int/uint
		WeaklyTypedInput: true,
	}

or

cfgLoader := config.NewWithOptions("", func(options *config.Options) {
    options.DefaultStructDecoderConfig = &mapstructure.DecoderConfig{
         DecodeHook : func(){}....

    }
})

hi @RelicOfTesla
In my test, Square does not affect the structure data embedded in the binding

Square=false(default)

config/export_test.go

Lines 141 to 184 in e7902e1

func TestMapStruct_embedded_struct_squash_false(t *testing.T) {
loader := NewWithOptions("test", func(options *Options) {
options.DecoderConfig.TagName = "json"
options.DecoderConfig.Squash = false
})
assert.False(t, loader.Options().DecoderConfig.Squash)
err := loader.LoadStrings(JSON, `
{
"c": "12",
"test1": {
"b": "34"
}
}
`)
assert.NoError(t, err)
dump.Println(loader.Data())
assert.Equal(t, 12, loader.Int("c"))
assert.Equal(t, 34, loader.Int("test1.b"))
type Test1 struct {
B int `json:"b"`
}
type Test2 struct {
Test1
C int `json:"c"`
}
cfg := &Test2{}
err = loader.MapStruct("", cfg)
assert.NoError(t, err)
dump.Println(cfg)
assert.Equal(t, 34, cfg.Test1.B)
type Test3 struct {
*Test1
C int `json:"c"`
}
cfg1 := &Test3{}
err = loader.MapStruct("", cfg1)
assert.NoError(t, err)
dump.Println(cfg1)
assert.Equal(t, 34, cfg1.Test1.B)
}

image

Square=true

on Square=true, if Test2.Test1 is not an ptr, the binding will not take effect

config/export_test.go

Lines 186 to 230 in e7902e1

func TestMapStruct_embedded_struct_squash_true(t *testing.T) {
loader := NewWithOptions("test", func(options *Options) {
options.DecoderConfig.TagName = "json"
options.DecoderConfig.Squash = true
})
assert.True(t, loader.Options().DecoderConfig.Squash)
err := loader.LoadStrings(JSON, `
{
"c": "12",
"test1": {
"b": "34"
}
}
`)
assert.NoError(t, err)
dump.Println(loader.Data())
assert.Equal(t, 12, loader.Int("c"))
assert.Equal(t, 34, loader.Int("test1.b"))
type Test1 struct {
B int `json:"b"`
}
type Test2 struct {
Test1
// Test1 `json:",squash"`
C int `json:"c"`
}
cfg := &Test2{}
err = loader.MapStruct("", cfg)
assert.NoError(t, err)
dump.Println(cfg)
assert.Equal(t, 0, cfg.Test1.B)
type Test3 struct {
*Test1
C int `json:"c"`
}
cfg1 := &Test3{}
err = loader.MapStruct("", cfg1)
assert.NoError(t, err)
dump.Println(cfg1)
assert.Equal(t, 34, cfg1.Test1.B)
}

image

your test json wrong...

json = {
 "c": "12",
 "b": "34"
}

now, has been add Options.DecoderConfig, can custom the mapstructure.DecoderConfig

eg:

loader := NewWithOptions("test", func(options *Options) { 
 		options.DecoderConfig.TagName = "json" 
 		options.DecoderConfig.Squash = true 
 	}) 

Released v2.0.23