aicra/validator/uint.go

68 lines
1.4 KiB
Go

package validator
import (
"encoding/json"
"math"
"reflect"
)
// UintType makes the "uint" type available in the aicra configuration
// It considers valid:
// - uint
// - int (since it does not overflow)
// - float64 (since it does not overflow)
// - strings containing json-compatible integers
// - []byte containing json-compatible integers
type UintType struct{}
// GoType returns the `uint` type
func (UintType) GoType() reflect.Type {
return reflect.TypeOf(uint(0))
}
// Validator for uint values
func (UintType) Validator(other string, avail ...Type) ValidateFunc {
if other != "uint" {
return nil
}
return func(value interface{}) (interface{}, bool) {
switch cast := value.(type) {
case int:
return uint(cast), cast >= 0
case uint:
return cast, true
case float64:
uintVal := uint(cast)
overflows := cast < 0 || cast > math.MaxUint64
return uintVal, cast == float64(uintVal) && !overflows
// serialized string -> try to convert to float
case string:
num := json.Number(cast)
floatVal, err := num.Float64()
if err != nil {
return 0, false
}
overflows := floatVal < 0 || floatVal > math.MaxUint64
return uint(floatVal), !overflows
case []byte:
num := json.Number(cast)
floatVal, err := num.Float64()
if err != nil {
return 0, false
}
overflows := floatVal < 0 || floatVal > math.MaxUint64
return uint(floatVal), !overflows
// unknown type
default:
return 0, false
}
}
}