diff --git a/pkg/rules/regex.go b/pkg/rules/regex.go new file mode 100644 index 0000000..ebcf9f1 --- /dev/null +++ b/pkg/rules/regex.go @@ -0,0 +1,34 @@ +package rules + +import ( + "regexp" + "sync" +) + +// nolint: lll +// Define all regular expressions here: +var ( + validUUIDRegexp = lazyRegexCompile(`^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`) + asciiRegexp = lazyRegexCompile(`^[\x00-\x7F]*$`) +) + +// lazyRegexCompile returns a function that compiles the regular expression +// once, when the function is called for the first time. +// If the function is never called, the regular expression is never compiled, +// thus saving on performance. +// +// All regular expression literals should be compiled using this function. +// +// Credits: https://github.com/go-playground/validator/commit/2e1df48b5ab876bdd461bdccc51d109389e7572f +func lazyRegexCompile(str string) func() *regexp.Regexp { + var ( + regex *regexp.Regexp + once sync.Once + ) + return func() *regexp.Regexp { + once.Do(func() { + regex = regexp.MustCompile(str) + }) + return regex + } +} diff --git a/pkg/rules/string.go b/pkg/rules/string.go index 9354305..3a7fe45 100644 --- a/pkg/rules/string.go +++ b/pkg/rules/string.go @@ -73,12 +73,9 @@ func StringDNSLabel() govy.RuleSet[string] { ).WithErrorCode(ErrorCodeStringDNSLabel) } -var validUUIDRegexp = regexp. - MustCompile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$") - // StringUUID ensures property's value is a valid UUID string. func StringUUID() govy.Rule[string] { - return StringMatchRegexp(validUUIDRegexp, + return StringMatchRegexp(validUUIDRegexp(), "00000000-0000-0000-0000-000000000000", "e190c630-8873-11ee-b9d1-0242ac120002", "79258D24-01A7-47E5-ACBB-7E762DE52298"). @@ -86,11 +83,9 @@ func StringUUID() govy.Rule[string] { WithErrorCode(ErrorCodeStringUUID) } -var asciiRegexp = regexp.MustCompile("^[\x00-\x7F]*$") - // StringASCII ensures property's value contains only ASCII characters. func StringASCII() govy.Rule[string] { - return StringMatchRegexp(asciiRegexp).WithErrorCode(ErrorCodeStringASCII) + return StringMatchRegexp(asciiRegexp()).WithErrorCode(ErrorCodeStringASCII) } // StringURL ensures property's value is a valid URL as defined by [url.Parse] function.