Skip to content

Commit 7c189ed

Browse files
feat(json): Add support for validating json numbers (#4)
1 parent 953d722 commit 7c189ed

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

minmax.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package validation
66

77
import (
8+
"encoding/json"
89
"fmt"
910
"reflect"
1011
"time"
@@ -82,6 +83,47 @@ func (r ThresholdRule) Validate(value any) error {
8283
return nil
8384
}
8485

86+
if jsonNumber, ok := value.(json.Number); ok {
87+
switch r.threshold.(type) {
88+
case int, int8, int16, int32, int64:
89+
// If our comparing number is an integer, then parse the json number as an
90+
// integer.
91+
i, err := jsonNumber.Int64()
92+
if err != nil {
93+
return err
94+
}
95+
value = i
96+
case uint, uint8, uint16, uint32, uint64:
97+
// If our comparing number is an unsigned integer, then parse the json
98+
// number as an integer and cast it.
99+
i, err := jsonNumber.Int64()
100+
if err != nil {
101+
return err
102+
}
103+
value = uint64(i)
104+
case float32, float64:
105+
// If our comparing value is a float, then parse the json number as a
106+
// float.
107+
f, err := jsonNumber.Float64()
108+
if err != nil {
109+
return err
110+
}
111+
value = f
112+
case time.Time:
113+
// If the value we have is a json number but we are comparing it to a time
114+
// object. Then assume it is a unix timestamp as a number.
115+
i, err := jsonNumber.Int64()
116+
if err != nil {
117+
return err
118+
}
119+
value = time.Unix(i, 0)
120+
}
121+
122+
if IsEmpty(value) {
123+
return nil
124+
}
125+
}
126+
85127
rv := reflect.ValueOf(r.threshold)
86128
switch rv.Kind() {
87129
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:

minmax_test.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package validation
66

77
import (
8+
"encoding/json"
89
"testing"
910
"time"
1011

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

2021
tests := []struct {
2122
tag string
22-
threshold interface{}
23+
threshold any
2324
exclusive bool
24-
value interface{}
25+
value any
2526
err string
2627
}{
2728
// int cases
@@ -55,6 +56,21 @@ func TestMin(t *testing.T) {
5556
{"t4.6", date20000601, true, 1, "cannot convert int to time.Time"},
5657
{"t4.7", struct{}{}, false, 1, "type not supported: struct {}"},
5758
{"t4.8", date0, false, date20000601, ""},
59+
// Json number cases
60+
{"t5.1", 1, false, json.Number("1"), ""},
61+
{"t5.2", 1, false, json.Number("2"), ""},
62+
{"t5.3", 1, false, json.Number("-1"), "must be no less than 1"},
63+
// This is so fucking stupid, 0 is considered "empty?" so even though 0 is
64+
// less than 1, this is considered okay?
65+
{"t5.4", float64(1), false, json.Number("0"), ""},
66+
{"t5.5", float64(1), true, json.Number("1"), "must be greater than 1"},
67+
{"t5.6", float64(1), false, json.Number("1"), ""},
68+
{"t5.7", float64(1), false, json.Number("2"), ""},
69+
{"t5.8", float64(1), false, json.Number("-1"), "must be no less than 1"},
70+
// This is so fucking stupid, 0 is considered "empty?" so even though 0 is
71+
// less than 1, this is considered okay?
72+
{"t5.9", float64(1), false, json.Number("0"), ""},
73+
{"t5.10", float64(1), true, json.Number("1"), "must be greater than 1"},
5874
}
5975

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

122145
for _, test := range tests {

0 commit comments

Comments
 (0)