Skip to content

struct to map Conversion Does Not Recursively Process Slices of Structs #120

@xyzdev-cell

Description

@xyzdev-cell

When converting a Go struct to a map[string]any using mapstructure, fields that are slices of structs ([]*MyStruct) are not recursively converted into slices of maps ([]map[string]any). Instead, the original []*MyStruct type is retained in the resulting map.

Problem Description:

Consider the following Go struct:

type WeaponState struct {
	Id int
}

Player{
  Weapons: []*WeaponState{
    {
    	Id:        10202001,
    },
    {
    	Id:        12201002,
    },
  },
}

Observed Behavior:

The Weapons field in the result map still holds a value of type []*WeaponState, rather than []map[string]any.

Upon inspecting the, I found that in the func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {} :

	switch v.Kind() {
	// this is an embedded struct, so handle it differently
	case reflect.Struct:
              // ...
              default:
		valMap.SetMapIndex(reflect.ValueOf(keyName), v)
	}

It appears that only reflect.Struct types are handled recursively. For any other reflect.Kind (including reflect.Slice), the value v is directly assigned to the valMap using SetMapIndex. This means that if a field is of reflect.Slice type, it bypasses any further recursive decoding or decodeHook application for its elements and is directly placed into the target map.

Question:

Is this behavior by design for the struct to map conversion, or is it an area that is yet to be improved or considered for deeper recursive conversion?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions