mitchellh / mapstructure

Go library for decoding generic map values into native Go structures and vice versa.
https://gist.github.com/mitchellh/90029601268e59a29e64e55bab1c5bdc
MIT License
7.93k stars 677 forks source link

Failed to decode nested structure #269

Closed gangtao closed 2 years ago

gangtao commented 2 years ago

I have a nested structure like this. and some fields failed to decode.

original stucture defined like this:

type Field struct {
    Name              string        `mapstructure:"name"`
    Type              FieldType     `mapstructure:"type"`
    Range             []interface{} `mapstructure:"range,omitempty"`
    Limit             []interface{} `mapstructure:"limit,omitempty"`
    TimestampFormat   string        `mapstructure:"timestamp_format,omitempty"`
    TimestampDelayMin int           `mapstructure:"timestamp_delay_min,omitempty"`
    TimestampDelayMax int           `mapstructure:"timestamp_delay_max,omitempty"`
}

type Configuration struct {
    BatchSize int     `mapstructure:"batch_size"`
    Internval int     `mapstructure:"interval"`
    Fields    []Field `mapstructure:"fields,omitempty"`
}

I have saved the whole config to file and reload it from the file. when I decode it, some field were missing like BatchSize, Internval , TimestampFormat etc. did I write the wrong code or it is an issue?

code :

    log.Infof("config %+v %T", config, config)

    var parsedConfiguration Configuration

    if err := mapstructure.Decode(config, &parsedConfiguration); err != nil {
        log.Error("the configuration is invalid", err)
        return nil, fmt.Errorf("invalid configuration")
    }

    log.Infof("parsed config %+v %T", parsedConfiguration, parsedConfiguration)

here is the log

INFO[0000] config map[BatchSize:1 Fields:[map[Limit:<nil> Name:device Range:[device_0 device_1 device_2] TimestampDelayMax:0 TimestampDelayMin:0 TimestampFormat: Type:string] map[Limit:[0 100] Name:number Range:<nil> TimestampDelayMax:0 TimestampDelayMin:0 TimestampFormat: Type:int] map[Limit:<nil> Name:time Range:<nil> TimestampDelayMax:0 TimestampDelayMin:0 TimestampFormat:2006-01-02 15:04:05.000 Type:timestamp]] Internval:200] map[string]interface {} 
INFO[0000] parsed config {BatchSize:0 Internval:0 Fields:[{Name:device Type:string Range:[device_0 device_1 device_2] Limit:[] TimestampFormat: TimestampDelayMin:0 TimestampDelayMax:0} {Name:number Type:int Range:[] Limit:[0 100] TimestampFormat: TimestampDelayMin:0 TimestampDelayMax:0} {Name:time Type:timestamp Range:[] Limit:[] TimestampFormat: TimestampDelayMin:0 TimestampDelayMax:0}]} generator.Configuration 
gangtao commented 2 years ago

Print with %=v, my version is 1.4.3

INFO[0000] config map[string]interface {}{"BatchSize":1, "Fields":[]interface {}{map[string]interface {}{"Limit":interface {}(nil), "Name":"device", "Range":[]interface {}{"device_0", "device_1", "device_2"}, "TimestampDelayMax":0, "TimestampDelayMin":0, "TimestampFormat":"", "Type":"string"}, map[string]interface {}{"Limit":[]interface {}{0, 100}, "Name":"number", "Range":interface {}(nil), "TimestampDelayMax":0, "TimestampDelayMin":0, "TimestampFormat":"", "Type":"int"}, map[string]interface {}{"Limit":interface {}(nil), "Name":"time", "Range":interface {}(nil), "TimestampDelayMax":0, "TimestampDelayMin":0, "TimestampFormat":"2006-01-02 15:04:05.000", "Type":"timestamp"}}, "Internval":200} map[string]interface {} 
INFO[0000] parsed config generator.Configuration{BatchSize:0, Internval:0, Fields:[]generator.Field{generator.Field{Name:"device", Type:"string", Range:[]interface {}{"device_0", "device_1", "device_2"}, Limit:[]interface {}(nil), TimestampFormat:"", TimestampDelayMin:0, TimestampDelayMax:0}, generator.Field{Name:"number", Type:"int", Range:[]interface {}(nil), Limit:[]interface {}{0, 100}, TimestampFormat:"", TimestampDelayMin:0, TimestampDelayMax:0}, generator.Field{Name:"time", Type:"timestamp", Range:[]interface {}(nil), Limit:[]interface {}(nil), TimestampFormat:"", TimestampDelayMin:0, TimestampDelayMax:0}}} generator.Configuration 
gangtao commented 2 years ago

I think I may have the wrong key due to the serialization. I will try to fix it.

mitchellh commented 2 years ago

This should work fine. If you can build a failing test case for me I'll take a closer look! Or, let me know if you're still having this issue. Thanks!