func doReifyPrimitive()

in reify.go [693:775]


func doReifyPrimitive(
	opts fieldOptions,
	val value,
	baseType reflect.Type,
) (reflect.Value, Error) {
	extras := map[reflect.Type]func(fieldOptions, value, reflect.Type) (reflect.Value, Error){
		tDuration: reifyDuration,
		tRegexp:   reifyRegexp,
	}

	previous := opts.opts.activeFields
	opts.opts.activeFields = newFieldSet(previous)
	valT, err := val.typ(opts.opts)
	if err != nil {
		ctx := val.Context()
		return reflect.Value{}, raisePathErr(err, val.meta(), "", ctx.path("."))
	}
	opts.opts.activeFields = previous

	// try primitive conversion
	kind := baseType.Kind()
	switch {
	case valT.gotype == baseType:
		v, err := val.reflect(opts.opts)
		if err != nil {
			ctx := val.Context()
			return reflect.Value{}, raisePathErr(err, val.meta(), "", ctx.path("."))
		}
		return v, nil

	case kind == reflect.String:
		s, err := val.toString(opts.opts)
		if err != nil {
			return reflect.Value{}, raiseConversion(opts.opts, val, err, "string")
		}
		return reflect.ValueOf(s), nil

	case extras[baseType] != nil:
		v, err := extras[baseType](opts, val, baseType)
		if err != nil {
			return v, err
		}
		return v, nil

	case isInt(kind):
		v, err := reifyInt(opts, val, baseType)
		if err != nil {
			return v, err
		}
		return v, nil

	case isUint(kind):
		v, err := reifyUint(opts, val, baseType)
		if err != nil {
			return v, err
		}
		return v, nil

	case isFloat(kind):
		v, err := reifyFloat(opts, val, baseType)
		if err != nil {
			return v, err
		}
		return v, nil

	case kind == reflect.Bool:
		v, err := reifyBool(opts, val, baseType)
		if err != nil {
			return v, err
		}
		return v, nil

	case valT.gotype.ConvertibleTo(baseType):
		v, err := val.reflect(opts.opts)
		if err != nil {
			ctx := val.Context()
			return reflect.Value{}, raisePathErr(err, val.meta(), "", ctx.path("."))
		}
		return v.Convert(baseType), nil
	}

	return reflect.Value{}, raiseToTypeNotSupported(opts.opts, val, baseType)
}