in document/cbor/decode.go [222:269]
func (d *decoder) decodeMap(tv cbor.Map, rv reflect.Value) error {
switch rv.Kind() {
case reflect.Map:
t := rv.Type()
if t.Key().Kind() != reflect.String {
return &document.UnmarshalTypeError{Value: "map string key", Type: t.Key()}
}
if rv.IsNil() {
rv.Set(reflect.MakeMap(t))
}
case reflect.Struct:
if rv.CanInterface() && document.IsNoSerde(rv.Interface()) {
return &document.UnmarshalTypeError{
Value: fmt.Sprintf("unsupported type"),
Type: rv.Type(),
}
}
case reflect.Interface:
rv.Set(reflect.MakeMap(serde.ReflectTypeOf.MapStringToInterface))
rv = rv.Elem()
default:
return &document.UnmarshalTypeError{Value: "map", Type: rv.Type()}
}
if rv.Kind() == reflect.Map {
for k, kv := range tv {
key := reflect.New(rv.Type().Key()).Elem()
key.SetString(k)
elem := reflect.New(rv.Type().Elem()).Elem()
if err := d.decode(kv, elem, serde.Tag{}); err != nil {
return err
}
rv.SetMapIndex(key, elem)
}
} else if rv.Kind() == reflect.Struct {
fields := serde.GetStructFields(rv.Type())
for k, kv := range tv {
if f, ok := fields.FieldByName(k); ok {
fv := serde.DecoderFieldByIndex(rv, f.Index)
if err := d.decode(kv, fv, f.Tag); err != nil {
return err
}
}
}
}
return nil
}