func reifyMap()

in reify.go [191:242]


func reifyMap(opts *options, to reflect.Value, from *Config, validators []validatorTag) Error {
	parentFields := opts.activeFields
	defer func() { opts.activeFields = parentFields }()

	if to.Type().Key().Kind() != reflect.String {
		return raiseKeyInvalidTypeUnpack(to.Type(), from)
	}

	if to.IsNil() {
		to.Set(reflect.MakeMap(to.Type()))
	}
	tryInitDefaults(to)

	fields := from.fields.dict()
	if len(fields) == 0 {
		if err := tryRecursiveValidate(to, opts, validators); err != nil {
			return raiseValidation(from.ctx, from.metadata, "", err)
		}
		return nil
	}

	for k, value := range fields {
		opts.activeFields = newFieldSet(parentFields)
		key := reflect.ValueOf(k)

		old := to.MapIndex(key)
		var v reflect.Value
		var err Error

		if !old.IsValid() {
			v, err = reifyValue(fieldOptions{opts: opts}, to.Type().Elem(), value)
		} else {
			v, err = reifyMergeValue(fieldOptions{opts: opts}, old, value)
		}

		if err != nil {
			return err
		}
		if v.IsValid() {
			to.SetMapIndex(key, v)
		}
	}

	if err := runValidators(to.Interface(), validators); err != nil {
		return raiseValidation(from.ctx, from.metadata, "", err)
	}
	if err := tryValidate(to); err != nil {
		return raiseValidation(from.ctx, from.metadata, "", err)
	}

	return nil
}