mirror of
https://github.com/google/uuid.git
synced 2025-02-18 12:24:00 +02:00
feat: Validate UUID without creating new UUID (#141)
* feat: Validate UUID without creating new UUID * fix: update comment
This commit is contained in:
parent
b35aa6a595
commit
9ee7366e66
53
uuid.go
53
uuid.go
@ -186,6 +186,59 @@ func Must(uuid UUID, err error) UUID {
|
||||
return uuid
|
||||
}
|
||||
|
||||
// Validate returns an error if s is not a properly formatted UUID in one of the following formats:
|
||||
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||
// It returns an error if the format is invalid, otherwise nil.
|
||||
func Validate(s string) error {
|
||||
switch len(s) {
|
||||
// Standard UUID format
|
||||
case 36:
|
||||
|
||||
// UUID with "urn:uuid:" prefix
|
||||
case 36 + 9:
|
||||
if !strings.EqualFold(s[:9], "urn:uuid:") {
|
||||
return fmt.Errorf("invalid urn prefix: %q", s[:9])
|
||||
}
|
||||
s = s[9:]
|
||||
|
||||
// UUID enclosed in braces
|
||||
case 36 + 2:
|
||||
if s[0] != '{' || s[len(s)-1] != '}' {
|
||||
return fmt.Errorf("invalid bracketed UUID format")
|
||||
}
|
||||
s = s[1 : len(s)-1]
|
||||
|
||||
// UUID without hyphens
|
||||
case 32:
|
||||
for i := 0; i < len(s); i += 2 {
|
||||
_, ok := xtob(s[i], s[i+1])
|
||||
if !ok {
|
||||
return errors.New("invalid UUID format")
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return invalidLengthError{len(s)}
|
||||
}
|
||||
|
||||
// Check for standard UUID format
|
||||
if len(s) == 36 {
|
||||
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
||||
return errors.New("invalid UUID format")
|
||||
}
|
||||
for _, x := range []int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} {
|
||||
if _, ok := xtob(s[x], s[x+1]); !ok {
|
||||
return errors.New("invalid UUID format")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
// , or "" if uuid is invalid.
|
||||
func (uuid UUID) String() string {
|
||||
|
29
uuid_test.go
29
uuid_test.go
@ -6,6 +6,7 @@ package uuid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
@ -605,6 +606,34 @@ func FuzzFromBytes(f *testing.F) {
|
||||
})
|
||||
}
|
||||
|
||||
// TestValidate checks various scenarios for the Validate function
|
||||
func TestValidate(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
input string
|
||||
expect error
|
||||
}{
|
||||
{"Valid UUID", "123e4567-e89b-12d3-a456-426655440000", nil},
|
||||
{"Valid UUID with URN", "urn:uuid:123e4567-e89b-12d3-a456-426655440000", nil},
|
||||
{"Valid UUID with Braces", "{123e4567-e89b-12d3-a456-426655440000}", nil},
|
||||
{"Valid UUID No Hyphens", "123e4567e89b12d3a456426655440000", nil},
|
||||
{"Invalid UUID", "invalid-uuid", errors.New("invalid UUID length: 12")},
|
||||
{"Invalid Length", "123", fmt.Errorf("invalid UUID length: %d", len("123"))},
|
||||
{"Invalid URN Prefix", "urn:test:123e4567-e89b-12d3-a456-426655440000", fmt.Errorf("invalid urn prefix: %q", "urn:test:")},
|
||||
{"Invalid Brackets", "[123e4567-e89b-12d3-a456-426655440000]", fmt.Errorf("invalid bracketed UUID format")},
|
||||
{"Invalid UUID Format", "12345678gabc1234abcd1234abcd1234", fmt.Errorf("invalid UUID format")},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := Validate(tc.input)
|
||||
if (err != nil) != (tc.expect != nil) || (err != nil && err.Error() != tc.expect.Error()) {
|
||||
t.Errorf("Validate(%q) = %v, want %v", tc.input, err, tc.expect)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var asString = "f47ac10b-58cc-0372-8567-0e02b2c3d479"
|
||||
var asBytes = []byte(asString)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user