Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions minmax.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package validation

import (
"encoding/json"
"fmt"
"reflect"
"time"
Expand Down Expand Up @@ -82,6 +83,47 @@ func (r ThresholdRule) Validate(value any) error {
return nil
}

if jsonNumber, ok := value.(json.Number); ok {
switch r.threshold.(type) {
case int, int8, int16, int32, int64:
// If our comparing number is an integer, then parse the json number as an
// integer.
i, err := jsonNumber.Int64()
if err != nil {
return err
}
value = i
case uint, uint8, uint16, uint32, uint64:
// If our comparing number is an unsigned integer, then parse the json
// number as an integer and cast it.
i, err := jsonNumber.Int64()
if err != nil {
return err
}
value = uint64(i)
case float32, float64:
// If our comparing value is a float, then parse the json number as a
// float.
f, err := jsonNumber.Float64()
if err != nil {
return err
}
value = f
case time.Time:
// If the value we have is a json number but we are comparing it to a time
// object. Then assume it is a unix timestamp as a number.
i, err := jsonNumber.Int64()
if err != nil {
return err
}
value = time.Unix(i, 0)
}

if IsEmpty(value) {
return nil
}
}

rv := reflect.ValueOf(r.threshold)
switch rv.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
Expand Down
27 changes: 25 additions & 2 deletions minmax_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package validation

import (
"encoding/json"
"testing"
"time"

Expand All @@ -19,9 +20,9 @@ func TestMin(t *testing.T) {

tests := []struct {
tag string
threshold interface{}
threshold any
exclusive bool
value interface{}
value any
err string
}{
// int cases
Expand Down Expand Up @@ -55,6 +56,21 @@ func TestMin(t *testing.T) {
{"t4.6", date20000601, true, 1, "cannot convert int to time.Time"},
{"t4.7", struct{}{}, false, 1, "type not supported: struct {}"},
{"t4.8", date0, false, date20000601, ""},
// Json number cases
{"t5.1", 1, false, json.Number("1"), ""},
{"t5.2", 1, false, json.Number("2"), ""},
{"t5.3", 1, false, json.Number("-1"), "must be no less than 1"},
// This is so fucking stupid, 0 is considered "empty?" so even though 0 is
// less than 1, this is considered okay?
{"t5.4", float64(1), false, json.Number("0"), ""},
{"t5.5", float64(1), true, json.Number("1"), "must be greater than 1"},
{"t5.6", float64(1), false, json.Number("1"), ""},
{"t5.7", float64(1), false, json.Number("2"), ""},
{"t5.8", float64(1), false, json.Number("-1"), "must be no less than 1"},
// This is so fucking stupid, 0 is considered "empty?" so even though 0 is
// less than 1, this is considered okay?
{"t5.9", float64(1), false, json.Number("0"), ""},
{"t5.10", float64(1), true, json.Number("1"), "must be greater than 1"},
}

for _, test := range tests {
Expand Down Expand Up @@ -117,6 +133,13 @@ func TestMax(t *testing.T) {
{"t4.4", date20000601, false, date0, ""},
{"t4.5", date20000601, true, date20000601, "must be less than 2000-06-01 00:00:00 +0000 UTC"},
{"t4.6", date20000601, true, 1, "cannot convert int to time.Time"},
{"t5.1", 2, false, json.Number("2"), ""},
{"t5.2", 2, false, json.Number("1"), ""},
{"t5.3", 2, false, json.Number("3"), "must be no greater than 2"},
// This is so fucking stupid, 0 is considered "empty?" so even though 0 is
// less than 1, this is considered okay?
{"t5.4", 2, false, json.Number("0"), ""},
{"t5.5", 2, true, json.Number("2"), "must be less than 2"},
}

for _, test := range tests {
Expand Down
Loading