Documentation
¶
Overview ¶
Package rules provides predefined rules for common validation scenarios.
Index ¶
- Constants
- func CompareDeepEqualFunc[T any](v1, v2 T) bool
- func CompareFunc[T comparable](v1, v2 T) bool
- func DurationPrecision(precision time.Duration) govy.Rule[time.Duration]
- func EQ[T comparable](compared T) govy.Rule[T]
- func EqualProperties[S, T any](compare ComparisonFunc[T], getters map[string]func(s S) T) govy.Rule[S]
- func Forbidden[T any]() govy.Rule[T]
- func GT[T cmp.Ordered](compared T) govy.Rule[T]
- func GTE[T cmp.Ordered](compared T) govy.Rule[T]
- func LT[T cmp.Ordered](compared T) govy.Rule[T]
- func LTE[T cmp.Ordered](compared T) govy.Rule[T]
- func MapLength[M ~map[K]V, K comparable, V any](minLen, maxLen int) govy.Rule[M]
- func MapMaxLength[M ~map[K]V, K comparable, V any](limit int) govy.Rule[M]
- func MapMinLength[M ~map[K]V, K comparable, V any](limit int) govy.Rule[M]
- func MutuallyExclusive[S any](required bool, getters map[string]func(s S) any) govy.Rule[S]
- func NEQ[T comparable](compared T) govy.Rule[T]
- func NotOneOf[T comparable](values ...T) govy.Rule[T]
- func OneOf[T comparable](values ...T) govy.Rule[T]
- func OneOfProperties[S any](getters map[string]func(s S) any) govy.Rule[S]
- func Required[T any]() govy.Rule[T]
- func SliceLength[S ~[]E, E any](minLen, maxLen int) govy.Rule[S]
- func SliceMaxLength[S ~[]E, E any](limit int) govy.Rule[S]
- func SliceMinLength[S ~[]E, E any](limit int) govy.Rule[S]
- func SliceUnique[S []V, V any, H comparable](hashFunc HashFunction[V, H], constraints ...string) govy.Rule[S]
- func StringASCII() govy.Rule[string]
- func StringAlpha() govy.Rule[string]
- func StringAlphaUnicode() govy.Rule[string]
- func StringAlphanumeric() govy.Rule[string]
- func StringAlphanumericUnicode() govy.Rule[string]
- func StringCIDR() govy.Rule[string]
- func StringCIDRv4() govy.Rule[string]
- func StringCIDRv6() govy.Rule[string]
- func StringContains(substrings ...string) govy.Rule[string]
- func StringCrontab() govy.Rule[string]
- func StringDNSLabel() govy.RuleSet[string]
- func StringDNSSubdomain() govy.RuleSet[string]
- func StringDateTime(layout string) govy.Rule[string]
- func StringDenyRegexp(re *regexp.Regexp) govy.Rule[string]
- func StringDirPath() govy.Rule[string]
- func StringEmail() govy.Rule[string]
- func StringEndsWith(suffixes ...string) govy.Rule[string]
- func StringExcludes(substrings ...string) govy.Rule[string]
- func StringFQDN() govy.Rule[string]
- func StringFilePath() govy.Rule[string]
- func StringFileSystemPath() govy.Rule[string]
- func StringGitRef() govy.Rule[string]
- func StringIP() govy.Rule[string]
- func StringIPv4() govy.Rule[string]
- func StringIPv6() govy.Rule[string]
- func StringJSON() govy.Rule[string]
- func StringKubernetesQualifiedName() govy.RuleSet[string]
- func StringLength(minLen, maxLen int) govy.Rule[string]
- func StringMAC() govy.Rule[string]
- func StringMatchFileSystemPath(pattern string) govy.Rule[string]
- func StringMatchRegexp(re *regexp.Regexp) govy.Rule[string]
- func StringMaxLength(limit int) govy.Rule[string]
- func StringMinLength(limit int) govy.Rule[string]
- func StringNotEmpty() govy.Rule[string]
- func StringRegexp() govy.Rule[string]
- func StringStartsWith(prefixes ...string) govy.Rule[string]
- func StringTimeZone() govy.Rule[string]
- func StringTitle() govy.Rule[string]
- func StringURL() govy.Rule[string]
- func StringUUID() govy.Rule[string]
- func URL() govy.Rule[*url.URL]
- type ComparisonFunc
- type HashFunction
Examples ¶
Constants ¶
const ( ErrorCodeRequired govy.ErrorCode = internal.RequiredErrorCodeString ErrorCodeForbidden govy.ErrorCode = "forbidden" ErrorCodeEqualTo govy.ErrorCode = "equal_to" ErrorCodeNotEqualTo govy.ErrorCode = "not_equal_to" ErrorCodeGreaterThan govy.ErrorCode = "greater_than" ErrorCodeGreaterThanOrEqualTo govy.ErrorCode = "greater_than_or_equal_to" ErrorCodeLessThan govy.ErrorCode = "less_than" ErrorCodeLessThanOrEqualTo govy.ErrorCode = "less_than_or_equal_to" ErrorCodeStringNotEmpty govy.ErrorCode = "string_not_empty" ErrorCodeStringMatchRegexp govy.ErrorCode = "string_match_regexp" ErrorCodeStringDenyRegexp govy.ErrorCode = "string_deny_regexp" ErrorCodeStringDNSLabel govy.ErrorCode = "string_dns_label" ErrorCodeStringDNSSubdomain govy.ErrorCode = "string_dns_subdomain" ErrorCodeStringURL govy.ErrorCode = "string_url" ErrorCodeStringMAC govy.ErrorCode = "string_mac" ErrorCodeStringIP govy.ErrorCode = "string_ip" ErrorCodeStringIPv4 govy.ErrorCode = "string_ipv4" ErrorCodeStringIPv6 govy.ErrorCode = "string_ipv6" ErrorCodeStringCIDR govy.ErrorCode = "string_cidr" ErrorCodeStringCIDRv4 govy.ErrorCode = "string_cidrv4" ErrorCodeStringCIDRv6 govy.ErrorCode = "string_cidrv6" ErrorCodeStringASCII govy.ErrorCode = "string_ascii" ErrorCodeStringUUID govy.ErrorCode = "string_uuid" ErrorCodeStringEmail govy.ErrorCode = "string_email" ErrorCodeStringJSON govy.ErrorCode = "string_json" ErrorCodeStringContains govy.ErrorCode = "string_contains" ErrorCodeStringExcludes govy.ErrorCode = "string_excludes" ErrorCodeStringStartsWith govy.ErrorCode = "string_starts_with" ErrorCodeStringEndsWith govy.ErrorCode = "string_ends_with" ErrorCodeStringLength govy.ErrorCode = "string_length" ErrorCodeStringMinLength govy.ErrorCode = "string_min_length" ErrorCodeStringMaxLength govy.ErrorCode = "string_max_length" ErrorCodeStringTitle govy.ErrorCode = "string_title" ErrorCodeStringGitRef govy.ErrorCode = "string_git_ref" ErrorCodeStringFileSystemPath govy.ErrorCode = "string_file_system_path" ErrorCodeStringMatchFileSystemPath govy.ErrorCode = "string_match_file_system_path" ErrorCodeStringFilePath govy.ErrorCode = "string_file_path" ErrorCodeStringDirPath govy.ErrorCode = "string_dir_path" ErrorCodeStringRegexp govy.ErrorCode = "string_regexp" ErrorCodeStringCrontab govy.ErrorCode = "string_crontab" ErrorCodeStringDateTime govy.ErrorCode = "string_date_time" ErrorCodeStringTimeZone govy.ErrorCode = "string_time_zone" ErrorCodeStringAlpha govy.ErrorCode = "string_alpha" ErrorCodeStringAlphanumeric govy.ErrorCode = "string_alphanumeric" ErrorCodeStringAlphaUnicode govy.ErrorCode = "string_alpha_unicode" ErrorCodeStringAlphanumericUnicode govy.ErrorCode = "string_alphanumeric_unicode" ErrorCodeStringFQDN govy.ErrorCode = "string_fqdn" ErrorCodeStringKubernetesQualifiedName govy.ErrorCode = "string_kubernetes_qualified_name" ErrorCodeSliceLength govy.ErrorCode = "slice_length" ErrorCodeSliceMinLength govy.ErrorCode = "slice_min_length" ErrorCodeSliceMaxLength govy.ErrorCode = "slice_max_length" ErrorCodeMapLength govy.ErrorCode = "map_length" ErrorCodeMapMinLength govy.ErrorCode = "map_min_length" ErrorCodeMapMaxLength govy.ErrorCode = "map_max_length" ErrorCodeOneOf govy.ErrorCode = "one_of" ErrorCodeNotOneOf govy.ErrorCode = "not_one_of" ErrorCodeOneOfProperties govy.ErrorCode = "one_of_properties" ErrorCodeMutuallyExclusive govy.ErrorCode = "mutually_exclusive" ErrorCodeEqualProperties govy.ErrorCode = "equal_properties" ErrorCodeSliceUnique govy.ErrorCode = "slice_unique" ErrorCodeURL govy.ErrorCode = "url" ErrorCodeDurationPrecision govy.ErrorCode = "duration_precision" )
Variables ¶
This section is empty.
Functions ¶
func CompareDeepEqualFunc ¶
CompareDeepEqualFunc compares two values of the same type using reflect.DeepEqual. It is particularly useful when comparing pointers' values.
func CompareFunc ¶
func CompareFunc[T comparable](v1, v2 T) bool
CompareFunc compares two values of the same type. The type is constrained by the [comparable] interface.
func DurationPrecision ¶
DurationPrecision ensures the duration is defined with the specified precision.
func EQ ¶
func EQ[T comparable](compared T) govy.Rule[T]
EQ ensures the property's value is equal to the compared value.
func EqualProperties ¶
func EqualProperties[S, T any](compare ComparisonFunc[T], getters map[string]func(s S) T) govy.Rule[S]
EqualProperties checks if all the specified properties are equal. It uses the provided ComparisonFunc to compare the values. The following built-in comparison functions are available:
If builtin ComparisonFunc is not enough, a custom function can be used.
Example ¶
package main
import (
"fmt"
"github.com/basicbrown/govy/pkg/govy"
"github.com/basicbrown/govy/pkg/rules"
)
type Teacher struct {
Students []Student `json:"students"`
}
type Student struct {
Index string `json:"index,omitempty"`
Name string `json:"name,omitempty"`
IndexCopy string `json:"indexCopy,omitempty"`
}
func main() {
v := govy.New(
govy.ForSlice(func(t Teacher) []Student { return t.Students }).
WithName("students").
RulesForEach(rules.EqualProperties(rules.CompareFunc, map[string]func(Student) any{
"index": func(s Student) any { return s.Index },
"indexCopy": func(s Student) any { return s.IndexCopy },
})),
)
teacher := Teacher{
Students: []Student{
{Index: "foo", IndexCopy: "foo"},
{Index: "bar"},
{IndexCopy: "foo"},
{}, // Both index and indexCopy are empty strings, and thus equal.
},
}
err := v.Validate(teacher)
if err != nil {
fmt.Println(err)
}
}
Output: Validation has failed for the following properties: - 'students[1]' with value '{"index":"bar"}': - all of [index, indexCopy] properties must be equal, but 'index' is not equal to 'indexCopy' - 'students[2]' with value '{"indexCopy":"foo"}': - all of [index, indexCopy] properties must be equal, but 'index' is not equal to 'indexCopy'
func MapLength ¶
func MapLength[M ~map[K]V, K comparable, V any](minLen, maxLen int) govy.Rule[M]
MapLength ensures the map's length is between min and max (closed interval).
The following, additional template variables are supported:
func MapMaxLength ¶
func MapMaxLength[M ~map[K]V, K comparable, V any](limit int) govy.Rule[M]
MapMaxLength ensures the map's length is less than or equal to the limit.
func MapMinLength ¶
func MapMinLength[M ~map[K]V, K comparable, V any](limit int) govy.Rule[M]
MapMinLength ensures the map's length is greater than or equal to the limit.
func MutuallyExclusive ¶
MutuallyExclusive checks if properties are mutually exclusive. This means, exactly one of the properties can be set. Property is considered set if its value is not empty (non-zero). If required is true, then a single non-empty property is required.
Example ¶
package main
import (
"fmt"
"github.com/basicbrown/govy/pkg/govy"
"github.com/basicbrown/govy/pkg/rules"
)
type Teacher struct {
Students []Student `json:"students"`
}
type Student struct {
Index string `json:"index,omitempty"`
Name string `json:"name,omitempty"`
IndexCopy string `json:"indexCopy,omitempty"`
}
func main() {
v := govy.New(
govy.ForSlice(func(t Teacher) []Student { return t.Students }).
WithName("students").
RulesForEach(rules.MutuallyExclusive(true, map[string]func(Student) any{
"index": func(s Student) any { return s.Index },
"name": func(s Student) any { return s.Name },
})),
)
teacher := Teacher{
Students: []Student{
{Index: "foo"},
{Index: "bar", Name: "John"},
{Name: "Eve"},
{},
},
}
err := v.Validate(teacher)
if err != nil {
fmt.Println(err)
}
}
Output: Validation has failed for the following properties: - 'students[1]' with value '{"index":"bar","name":"John"}': - [index, name] properties are mutually exclusive, provide only one of them - 'students[3]': - one of [index, name] properties must be set, none was provided
func NEQ ¶
func NEQ[T comparable](compared T) govy.Rule[T]
NEQ ensures the property's value is not equal to the compared value.
func NotOneOf ¶
func NotOneOf[T comparable](values ...T) govy.Rule[T]
NotOneOf checks if the property's value does not match any of the provided values. The values must be comparable.
For reversed rule see OneOf.
func OneOf ¶
func OneOf[T comparable](values ...T) govy.Rule[T]
OneOf checks if the property's value matches one of the provided values. The values must be comparable.
For reversed rule see NotOneOf.
func OneOfProperties ¶
OneOfProperties checks if at least one of the properties is set. Property is considered set if its value is not empty (non-zero).
Example ¶
package main
import (
"fmt"
"github.com/basicbrown/govy/pkg/govy"
"github.com/basicbrown/govy/pkg/rules"
)
type Teacher struct {
Students []Student `json:"students"`
}
type Student struct {
Index string `json:"index,omitempty"`
Name string `json:"name,omitempty"`
IndexCopy string `json:"indexCopy,omitempty"`
}
func main() {
v := govy.New(
govy.ForSlice(func(t Teacher) []Student { return t.Students }).
WithName("students").
RulesForEach(rules.OneOfProperties(map[string]func(Student) any{
"index": func(s Student) any { return s.Index },
"name": func(s Student) any { return s.Name },
})),
)
teacher := Teacher{
Students: []Student{
{Index: "foo"},
{},
{Name: "John"},
{Index: "bar", Name: "Eve"},
},
}
err := v.Validate(teacher)
if err != nil {
fmt.Println(err)
}
}
Output: Validation has failed for the following properties: - 'students[1]': - one of [index, name] properties must be set, none was provided
func Required ¶
Required ensures the property's value is not empty (i.e. it's not its type's zero value).
func SliceLength ¶
SliceLength ensures the slice's length is between min and max (closed interval).
The following, additional template variables are supported:
func SliceMaxLength ¶
SliceMaxLength ensures the slice's length is less than or equal to the limit.
func SliceMinLength ¶
SliceMinLength ensures the slice's length is greater than or equal to the limit.
func SliceUnique ¶
func SliceUnique[S []V, V any, H comparable](hashFunc HashFunction[V, H], constraints ...string) govy.Rule[S]
SliceUnique ensures that a slice contains unique elements based on a provided HashFunction. You can optionally specify constraints which will be included in the error message to further clarify the reason for breaking uniqueness.
Example ¶
package main
import (
"fmt"
"github.com/basicbrown/govy/pkg/govy"
"github.com/basicbrown/govy/pkg/rules"
)
type Teacher struct {
Students []Student `json:"students"`
}
type Student struct {
Index string `json:"index,omitempty"`
Name string `json:"name,omitempty"`
IndexCopy string `json:"indexCopy,omitempty"`
}
func main() {
v := govy.New(
govy.ForSlice(func(t Teacher) []Student { return t.Students }).
WithName("students").
Rules(rules.SliceUnique(func(v Student) string { return v.Index },
"each student must have unique index")),
)
teacher := Teacher{
Students: []Student{
{Index: "foo"},
{Index: "bar"}, // 2nd element
{Index: "baz"},
{Index: "bar"}, // 4th element
},
}
err := v.Validate(teacher)
if err != nil {
fmt.Println(err)
}
}
Output: Validation has failed for the following properties: - 'students' with value '[{"index":"foo"},{"index":"bar"},{"index":"baz"},{"index":"bar"}]': - elements are not unique, 2nd and 4th elements collide based on constraints: each student must have unique index
func StringASCII ¶
StringASCII ensures property's value contains only ASCII characters.
func StringAlpha ¶
StringAlpha ensures the property's value consists only of ASCII letters.
func StringAlphaUnicode ¶
StringAlphaUnicode ensures the property's value consists only of Unicode letters.
func StringAlphanumeric ¶
StringAlphanumeric ensures the property's value consists only of ASCII letters and numbers.
func StringAlphanumericUnicode ¶
StringAlphanumericUnicode ensures the property's value consists only of Unicode letters and numbers.
func StringCIDR ¶
StringCIDR ensures property's value is a valid CIDR notation IP address.
func StringCIDRv4 ¶
StringCIDRv4 ensures property's value is a valid CIDR notation IPv4 address.
func StringCIDRv6 ¶
StringCIDRv6 ensures property's value is a valid CIDR notation IPv6 address.
func StringContains ¶
StringContains ensures the property's value contains all the provided substrings.
func StringCrontab ¶
StringCrontab ensures the property's value is a valid crontab schedule expression. For more details on cron expressions read crontab manual and visit crontab.guru.
func StringDNSLabel ¶
StringDNSLabel ensures the property's value is a valid DNS label as defined by RFC 1123.
func StringDNSSubdomain ¶
StringDNSSubdomain ensures the property's value is a valid DNS subdomain as defined by RFC 1123.
func StringDateTime ¶
StringDateTime ensures the property's value is a valid date and time in the specified layout.
The layout must be a valid time format string as defined by time.Parse, an example of which is time.RFC3339.
func StringDenyRegexp ¶
StringDenyRegexp ensures the property's value does not match the regular expression. The error message can be enhanced with examples of invalid values.
func StringDirPath ¶
StringDirPath ensures the property's value is a file system path pointing to an existing directory.
func StringEmail ¶
StringEmail ensures the property's value is a valid email address. It follows RFC 5322 specification which is more permissive in regards to domain names.
func StringEndsWith ¶
StringEndsWith ensures the property's value ends with one of the provided suffixes.
func StringExcludes ¶
StringExcludes ensures the property's value does not contain any of the provided substrings.
func StringFQDN ¶
StringFQDN ensures the property's value is a fully qualified domain name (FQDN).
func StringFilePath ¶
StringFilePath ensures the property's value is a file system path pointing to an existing file.
func StringFileSystemPath ¶
StringFileSystemPath ensures the property's value is an existing file system path.
func StringGitRef ¶
StringGitRef ensures a git reference name follows the [git-check-ref-format] rules.
It is important to note that this function does not check if the reference exists in the repository. It only checks if the reference name is valid. This functions does not support the '--refspec-pattern', '--normalize', and '--allow-onelevel' options.
Git imposes the following rules on how references are named:
- They can include slash '/' for hierarchical (directory) grouping, but no slash-separated component can begin with a dot '.' or end with the sequence '.lock'.
- They must contain at least one '/'. This enforces the presence of a category (e.g. 'heads/', 'tags/'), but the actual names are not restricted.
- They cannot have ASCII control characters (i.e. bytes whose values are lower than '\040', or '\177' DEL).
- They cannot have '?', '*', '[', ' ', '~', '^', ', '\t', '\n', '@{', '\\' and '..',
- They cannot begin or end with a slash '/'.
- They cannot end with a '.'.
- They cannot be the single character '@'.
- 'HEAD' is an allowed special name.
Slightly modified version of [go-git] implementation, kudos to the authors!
[git-check-ref-format] :https://git-scm.com/docs/git-check-ref-format [go-git]: https://github.com/go-git/go-git/blob/95afe7e1cdf71c59ee8a71971fac71880020a744/plumbing/reference.go#L167
func StringIPv4 ¶
StringIPv4 ensures property's value is a valid IPv4 address.
func StringIPv6 ¶
StringIPv6 ensures property's value is a valid IPv6 address.
func StringJSON ¶
StringJSON ensures property's value is a valid JSON literal.
func StringKubernetesQualifiedName ¶
StringKubernetesQualifiedName ensures the property's value is a valid "qualified name" as defined by Kubernetes validation. The qualified name is used in various parts of the Kubernetes system, examples:
- annotation names
- label names
func StringLength ¶
StringLength ensures the string's length is between min and max (closed interval).
The following, additional template variables are supported:
func StringMatchFileSystemPath ¶
StringMatchFileSystemPath ensures the property's value matches the provided file path pattern. It uses filepath.Match to match the pattern. The native function comes with some limitations, most notably it does not support '**' recursive expansion. It does not check if the file path exists on the file system.
func StringMatchRegexp ¶
StringMatchRegexp ensures the property's value matches the regular expression. The error message can be enhanced with examples of valid values.
func StringMaxLength ¶
StringMaxLength ensures the string's length is less than or equal to the limit.
func StringMinLength ¶
StringMinLength ensures the string's length is greater than or equal to the limit.
func StringNotEmpty ¶
StringNotEmpty ensures the property's value is not empty. The string is considered empty if it contains only whitespace characters.
func StringRegexp ¶
StringRegexp ensures the property's value is a valid regular expression. The accepted regular expression syntax must comply to RE2. It is described at https://golang.org/s/re2syntax, except for \C. For an overview of the syntax, see regexp/syntax package.
func StringStartsWith ¶
StringStartsWith ensures the property's value starts with one of the provided prefixes.
func StringTimeZone ¶
StringTimeZone ensures the property's value is a valid time zone name which uniquely identifies a time zone in the IANA Time Zone database. Example: "America/New_York", "Europe/London".
Under the hood time.LoadLocation is called to parse the zone. The native function allows empty string and 'Local' keyword to be supplied. However, these two options are explicitly forbidden by StringTimeZone.
Furthermore, the time zone data is not readily available in one predefined place. time.LoadLocation looks for the IANA Time Zone database in specific places, please refer to its documentation for more information.
func StringTitle ¶
StringTitle ensures each word in a string starts with a capital letter.
func StringURL ¶
StringURL ensures property's value is a valid URL as defined by url.Parse function. Unlike URL it does not impose any additional rules upon parsed url.URL.
func StringUUID ¶
StringUUID ensures property's value is a valid UUID string as defined by RFC 4122. It does not enforce a specific UUID version.
Types ¶
type ComparisonFunc ¶
ComparisonFunc defines a shape for a function that compares two values. It should return true if the values are equal, false otherwise.
type HashFunction ¶
type HashFunction[V any, H comparable] func(v V) H
HashFunction accepts a value and returns a comparable hash.
func HashFuncSelf ¶
func HashFuncSelf[H comparable]() HashFunction[H, H]
HashFuncSelf returns a HashFunction which returns its input value as a hash itself. The value must be comparable.