Skip to content

Commit 45664ca

Browse files
committed
Use sync.OnceValue only on go1.21+
sync.OnceValue was introduced in go1.21. Currently validator's go.mod states minimum go version to be go1.18. This commit moves the lazy regex initialization into its own file lazy.go and provides backwards compatibility using buildtags and the file lazy_compat.go which contains a backported (non-generic) version of sync.OnceValue. Signed-off-by: Kimmo Lehto <[email protected]>
1 parent c111ad2 commit 45664ca

File tree

3 files changed

+60
-11
lines changed

3 files changed

+60
-11
lines changed

lazy.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//go:build go1.21
2+
3+
package validator
4+
5+
import (
6+
"regexp"
7+
"sync"
8+
)
9+
10+
func lazyRegexCompile(str string) func() *regexp.Regexp {
11+
return sync.OnceValue(func() *regexp.Regexp {
12+
return regexp.MustCompile(str)
13+
})
14+
}

lazy_compat.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//go:build !go1.21
2+
3+
package validator
4+
5+
import (
6+
"regexp"
7+
"sync"
8+
)
9+
10+
// Copied and adapted from go1.21 stdlib's sync.OnceValue for backwards compatibility:
11+
// OnceValue returns a function that invokes f only once and returns the value
12+
// returned by f. The returned function may be called concurrently.
13+
//
14+
// If f panics, the returned function will panic with the same value on every call.
15+
func onceValue(f func() *regexp.Regexp) func() *regexp.Regexp {
16+
var (
17+
once sync.Once
18+
valid bool
19+
p any
20+
result *regexp.Regexp
21+
)
22+
g := func() {
23+
defer func() {
24+
p = recover()
25+
if !valid {
26+
panic(p)
27+
}
28+
}()
29+
result = f()
30+
f = nil
31+
valid = true
32+
}
33+
return func() *regexp.Regexp {
34+
once.Do(g)
35+
if !valid {
36+
panic(p)
37+
}
38+
return result
39+
}
40+
}
41+
42+
func lazyRegexCompile(str string) func() *regexp.Regexp {
43+
return onceValue(func() *regexp.Regexp {
44+
return regexp.MustCompile(str)
45+
})
46+
}

regexes.go

-11
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
package validator
22

3-
import (
4-
"regexp"
5-
"sync"
6-
)
7-
83
const (
94
alphaRegexString = "^[a-zA-Z]+$"
105
alphaNumericRegexString = "^[a-zA-Z0-9]+$"
@@ -79,12 +74,6 @@ const (
7974
spicedbTypeRegexString = "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)?[a-z][a-z0-9_]{1,62}[a-z0-9]$"
8075
)
8176

82-
func lazyRegexCompile(str string) func() *regexp.Regexp {
83-
return sync.OnceValue(func() *regexp.Regexp {
84-
return regexp.MustCompile(str)
85-
})
86-
}
87-
8877
var (
8978
alphaRegex = lazyRegexCompile(alphaRegexString)
9079
alphaNumericRegex = lazyRegexCompile(alphaNumericRegexString)

0 commit comments

Comments
 (0)