Skip to content

Commit 7aa7084

Browse files
joeybloggsjoeybloggs
authored andcommitted
add uuid, uuid3, uuid4 and uuid5 validators + tests + documentation
1 parent 20d9b79 commit 7aa7084

File tree

4 files changed

+162
-0
lines changed

4 files changed

+162
-0
lines changed

baked_in.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,26 @@ var BakedInValidators = map[string]Func{
5353
"isbn": isISBN,
5454
"isbn10": isISBN10,
5555
"isbn13": isISBN13,
56+
"uuid": isUUID,
57+
"uuid3": isUUID3,
58+
"uuid4": isUUID4,
59+
"uuid5": isUUID5,
60+
}
61+
62+
func isUUID5(top interface{}, current interface{}, field interface{}, param string) bool {
63+
return matchesRegex(uUID5Regex, field)
64+
}
65+
66+
func isUUID4(top interface{}, current interface{}, field interface{}, param string) bool {
67+
return matchesRegex(uUID4Regex, field)
68+
}
69+
70+
func isUUID3(top interface{}, current interface{}, field interface{}, param string) bool {
71+
return matchesRegex(uUID3Regex, field)
72+
}
73+
74+
func isUUID(top interface{}, current interface{}, field interface{}, param string) bool {
75+
return matchesRegex(uUIDRegex, field)
5676
}
5777

5878
func isISBN(top interface{}, current interface{}, field interface{}, param string) bool {

doc.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,22 @@ Here is a list of the current built in validators:
374374
This validates that a string value contains a valid isbn13 value.
375375
(Usage: isbn13)
376376
377+
uuid
378+
This validates that a string value contains a valid UUID.
379+
(Usage: uuid)
380+
381+
uuid3
382+
This validates that a string value contains a valid version 3 UUID.
383+
(Usage: uuid3)
384+
385+
uuid4
386+
This validates that a string value contains a valid version 4 UUID.
387+
(Usage: uuid4)
388+
389+
uuid5
390+
This validates that a string value contains a valid version 5 UUID.
391+
(Usage: uuid5)
392+
377393
Validator notes:
378394
379395
regex

regexes.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ const (
1717
base64RegexString = "(?:^(?:[A-Za-z0-9+\\/]{4}\\n?)*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=)$)"
1818
iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$"
1919
iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$"
20+
uUID3RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
21+
uUID4RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
22+
uUID5RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
23+
uUIDRegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
2024
)
2125

2226
var (
@@ -34,6 +38,10 @@ var (
3438
base64Regex = regexp.MustCompile(base64RegexString)
3539
iSBN10Regex = regexp.MustCompile(iSBN10RegexString)
3640
iSBN13Regex = regexp.MustCompile(iSBN13RegexString)
41+
uUID3Regex = regexp.MustCompile(uUID3RegexString)
42+
uUID4Regex = regexp.MustCompile(uUID4RegexString)
43+
uUID5Regex = regexp.MustCompile(uUID5RegexString)
44+
uUIDRegex = regexp.MustCompile(uUIDRegexString)
3745
)
3846

3947
func matchesRegex(regex *regexp.Regexp, field interface{}) bool {

validator_test.go

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,124 @@ func AssertMapFieldError(t *testing.T, s map[string]*FieldError, field string, e
226226
EqualSkip(t, 2, val.Tag, expectedTag)
227227
}
228228

229+
func TestUUID5Validation(t *testing.T) {
230+
tests := []struct {
231+
param string
232+
expected bool
233+
}{
234+
235+
{"", false},
236+
{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
237+
{"9c858901-8a57-4791-81fe-4c455b099bc9", false},
238+
{"a987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
239+
{"987fbc97-4bed-5078-af07-9141ba07c9f3", true},
240+
{"987fbc97-4bed-5078-9f07-9141ba07c9f3", true},
241+
}
242+
243+
for i, test := range tests {
244+
245+
err := validate.Field(test.param, "uuid5")
246+
247+
if test.expected == true {
248+
if !IsEqual(t, err, nil) {
249+
t.Fatalf("Index: %d UUID5 failed Error: %s", i, err)
250+
}
251+
} else {
252+
if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "uuid5") {
253+
t.Fatalf("Index: %d UUID5 failed Error: %s", i, err)
254+
}
255+
}
256+
}
257+
}
258+
259+
func TestUUID4Validation(t *testing.T) {
260+
tests := []struct {
261+
param string
262+
expected bool
263+
}{
264+
{"", false},
265+
{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
266+
{"a987fbc9-4bed-5078-af07-9141ba07c9f3", false},
267+
{"934859", false},
268+
{"57b73598-8764-4ad0-a76a-679bb6640eb1", true},
269+
{"625e63f3-58f5-40b7-83a1-a72ad31acffb", true},
270+
}
271+
272+
for i, test := range tests {
273+
274+
err := validate.Field(test.param, "uuid4")
275+
276+
if test.expected == true {
277+
if !IsEqual(t, err, nil) {
278+
t.Fatalf("Index: %d UUID4 failed Error: %s", i, err)
279+
}
280+
} else {
281+
if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "uuid4") {
282+
t.Fatalf("Index: %d UUID4 failed Error: %s", i, err)
283+
}
284+
}
285+
}
286+
}
287+
288+
func TestUUID3Validation(t *testing.T) {
289+
tests := []struct {
290+
param string
291+
expected bool
292+
}{
293+
{"", false},
294+
{"412452646", false},
295+
{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
296+
{"a987fbc9-4bed-4078-8f07-9141ba07c9f3", false},
297+
{"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true},
298+
}
299+
300+
for i, test := range tests {
301+
302+
err := validate.Field(test.param, "uuid3")
303+
304+
if test.expected == true {
305+
if !IsEqual(t, err, nil) {
306+
t.Fatalf("Index: %d UUID3 failed Error: %s", i, err)
307+
}
308+
} else {
309+
if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "uuid3") {
310+
t.Fatalf("Index: %d UUID3 failed Error: %s", i, err)
311+
}
312+
}
313+
}
314+
}
315+
316+
func TestUUIDValidation(t *testing.T) {
317+
tests := []struct {
318+
param string
319+
expected bool
320+
}{
321+
{"", false},
322+
{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
323+
{"a987fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false},
324+
{"a987fbc94bed3078cf079141ba07c9f3", false},
325+
{"934859", false},
326+
{"987fbc9-4bed-3078-cf07a-9141ba07c9f3", false},
327+
{"aaaaaaaa-1111-1111-aaag-111111111111", false},
328+
{"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true},
329+
}
330+
331+
for i, test := range tests {
332+
333+
err := validate.Field(test.param, "uuid")
334+
335+
if test.expected == true {
336+
if !IsEqual(t, err, nil) {
337+
t.Fatalf("Index: %d UUID failed Error: %s", i, err)
338+
}
339+
} else {
340+
if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "uuid") {
341+
t.Fatalf("Index: %d UUID failed Error: %s", i, err)
342+
}
343+
}
344+
}
345+
}
346+
229347
func TestISBNValidation(t *testing.T) {
230348
tests := []struct {
231349
param string

0 commit comments

Comments
 (0)