add Required, Prefix, Suffix, Contains, Match validators

Broadens the built-in set with the string/presence checks that came up
most often when reaching for this package:

  - Required[T comparable]  non-zero value
  - Prefix / Suffix / Contains  strings.HasPrefix/HasSuffix/Contains
  - Match(*regexp.Regexp)  arbitrary pattern

All follow the existing shape: a constructor returning func(T) error, a
sentinel error matched with errors.Is, table-driven tests and an Example.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit was merged in pull request #9.
This commit is contained in:
2026-09-07 12:51:42 +00:00
committed by aneurin
co-authored by Claude Sonnet 5
parent e65d7d66c1
commit 82611a5e96
6 changed files with 232 additions and 0 deletions
+69
View File
@@ -0,0 +1,69 @@
package validate
import (
"errors"
"fmt"
"testing"
)
func ExamplePrefix() {
fmt.Println(Prefix("https://")("http://example.com"))
// Output: must start with "https://"
}
func TestPrefix(t *testing.T) {
testCases := map[string]error{
"https://example.com": nil,
"https://": nil,
"http://example.com": ErrMissingPrefix.With("https://"),
"": ErrMissingPrefix.With("https://"),
}
v := Prefix("https://")
for input, want := range testCases {
t.Run(input, func(t *testing.T) {
if got := v(input); !errors.Is(got, want) {
t.Error("got", got, "want", want)
}
})
}
}
func TestSuffix(t *testing.T) {
testCases := map[string]error{
"report.pdf": nil,
".pdf": nil,
"report.txt": ErrMissingSuffix.With(".pdf"),
"pdf": ErrMissingSuffix.With(".pdf"),
}
v := Suffix(".pdf")
for input, want := range testCases {
t.Run(input, func(t *testing.T) {
if got := v(input); !errors.Is(got, want) {
t.Error("got", got, "want", want)
}
})
}
}
func TestContains(t *testing.T) {
testCases := map[string]error{
"a b c": nil,
" ": nil,
"abc": ErrMissingSubstring.With(" "),
"": ErrMissingSubstring.With(" "),
}
v := Contains(" ")
for input, want := range testCases {
t.Run(input, func(t *testing.T) {
if got := v(input); !errors.Is(got, want) {
t.Error("got", got, "want", want)
}
})
}
}