Skip to content

Commit 4ccd19c

Browse files
enhance #10 : avoid allocations on parseUUID
2 parents a206a17 + 4c42601 commit 4ccd19c

File tree

2 files changed

+94
-5
lines changed

2 files changed

+94
-5
lines changed

helper.go

+22-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"encoding/hex"
55
"errors"
66
"fmt"
7-
"strings"
87
)
98

109
// Helper function to encode timestamp into the UUID byte array.
@@ -29,14 +28,32 @@ func decodeTimestamp(uuidBytes []byte) uint64 {
2928
uint64(uuidBytes[3])<<16 | uint64(uuidBytes[4])<<8 | uint64(uuidBytes[5])
3029
}
3130

31+
// Helper function to parse and sanitize a UUID string.
3232
// Helper function to parse and sanitize a UUID string.
3333
func parseUUID(uuid string) ([]byte, error) {
34-
uuid = strings.ReplaceAll(uuid, "-", "")
35-
if len(uuid) != 32 {
34+
switch len(uuid) {
35+
case 32:
36+
// Fast path for UUIDs without dashes
37+
return hex.DecodeString(uuid)
38+
case 36:
39+
// Validate dash positions
40+
if uuid[8] != '-' || uuid[13] != '-' || uuid[18] != '-' || uuid[23] != '-' {
41+
return nil, errors.New("invalid UUID format")
42+
}
43+
44+
// Remove dashes while copying characters
45+
result := make([]byte, 32)
46+
j := 0
47+
for i := 0; i < len(uuid); i++ {
48+
if uuid[i] != '-' {
49+
result[j] = uuid[i]
50+
j++
51+
}
52+
}
53+
return hex.DecodeString(string(result))
54+
default:
3655
return nil, errors.New("invalid UUID length")
3756
}
38-
39-
return hex.DecodeString(uuid)
4057
}
4158

4259
// Helper function to check if a UUID is all zeros.

uuidv8_test.go

+72
Original file line numberDiff line numberDiff line change
@@ -720,3 +720,75 @@ func TestUUIDv8_Scan_EdgeCases(t *testing.T) {
720720
})
721721
}
722722
}
723+
724+
func TestFromString_InvalidInputs(t *testing.T) {
725+
tests := []string{
726+
"123", // Too short
727+
"123e4567e89b12d3a4564266141740000000", // Too long
728+
"123e4567e89b12d3a45642661417400g", // Invalid character
729+
"123e-4567-e89b-12d3-a456-426614174000", // Misplaced dashes
730+
"123e4567-e89b-12d3-a456-426614174000-", // Extra dash at the end
731+
"--123e4567-e89b-12d3-a456-426614174000", // Extra dash at the start
732+
"123e4567-e89b-12d3-a456-42-6614174000", // Randomly placed dash
733+
"------------------------------------", // 36 dashes
734+
"9a3d4049-0e2c-8080-0102-030405060000", // Valid UUID with dashes
735+
}
736+
737+
for _, input := range tests {
738+
t.Run("Testing UUID: "+input, func(t *testing.T) {
739+
_, err := uuidv8.FromString(input)
740+
// The last case is valid; others should fail
741+
if input == "9a3d4049-0e2c-8080-0102-030405060000" {
742+
if err != nil {
743+
t.Errorf("Expected valid UUID but got error for input: %s", input)
744+
}
745+
} else {
746+
if err == nil {
747+
t.Errorf("Expected error, got nil for input: %s", input)
748+
}
749+
}
750+
})
751+
}
752+
}
753+
754+
func TestFromStringOrNil_InvalidInputs(t *testing.T) {
755+
tests := []string{
756+
"123", // Too short
757+
"123e4567e89b12d3a4564266141740000000", // Too long
758+
"123e4567e89b12d3a45642661417400g", // Invalid character
759+
"", // Empty string
760+
"123e4567-e89b-12d3-a456-426614174000-", // Extra dash at the end
761+
"--123e4567-e89b-12d3-a456-426614174000", // Extra dash at the start
762+
"123e4567-e89b-12d3-a456-42-6614174000", // Randomly placed dash
763+
}
764+
765+
for _, input := range tests {
766+
t.Run("Invalid UUID "+input, func(t *testing.T) {
767+
result := uuidv8.FromStringOrNil(input)
768+
if result != nil {
769+
t.Errorf("Expected nil for input: %s, got %v", input, result)
770+
}
771+
})
772+
}
773+
}
774+
775+
func TestIsValidUUIDv8_InvalidUUIDs(t *testing.T) {
776+
invalidUUIDs := []string{
777+
"123", // Too short
778+
"123e4567e89b12d3a4564266141740000000", // Too long
779+
"123e4567e89b12d3a45642661417400g", // Invalid character
780+
"", // Empty string
781+
"123e4567-e89b-12d3-a456-426614174000-", // Extra dash at the end
782+
"--123e4567-e89b-12d3-a456-426614174000", // Extra dash at the start
783+
"123e4567-e89b-12d3-a456-42-6614174000", // Randomly placed dash
784+
785+
}
786+
787+
for _, uuid := range invalidUUIDs {
788+
t.Run("Invalid UUID "+uuid, func(t *testing.T) {
789+
if uuidv8.IsValidUUIDv8(uuid) {
790+
t.Errorf("Expected UUID %s to be invalid", uuid)
791+
}
792+
})
793+
}
794+
}

0 commit comments

Comments
 (0)