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)
}