Rules
The rule set, the RuleFunc contract, and the built-in required and oneof rules.
Rules validate a field's input. They are declared per field in the rules: tag and resolved against a rule set keyed by name. See Validation for the task-level walkthrough.
DefaultRules
var DefaultRules = map[string]RuleFunc{
"required": Required,
"oneof": OneOf,
}The built-in rule set, keyed by the name used in a rules: tag. Pass it to New or ValidateStructFields, or build your own map (optionally extending this one) to register custom RuleFuncs.
RuleFunc
type RuleFunc func(fieldName string, values map[string]any, defaultValue string, fieldValue reflect.Value, args []string) (map[string][]string, error)Validates one field against one rule. It receives the lookup key (fieldName, already resolved by tag priority), the full input values, the field's default, its reflect.Value, and the rule's args. It returns a map of field name to error messages, empty when valid. The returned error is for internal failures only, not validation failures.
Rule
type Rule struct {
// Name is the rule identifier, used to look up its RuleFunc in the rule set.
Name string
// Args are the colon-suffixed, comma-separated arguments, nil if none.
Args []string
}A single validation rule parsed from a rules: tag entry. For rules:"oneof:json,yaml", Name is "oneof" and Args is ["json", "yaml"].
Required
var Required RuleFuncFails when a field has no non-empty input, no default, and a zero current value. Whitespace-only string input counts as empty.
OneOf
var OneOf RuleFuncRestricts a field to one of the values listed in the rule args, e.g. rules:"oneof:json,yaml,toml". An empty or absent value passes on its own, so pair it with required to force presence. When a default is set, the default is what gets checked if no input was provided.
Writing a custom rule
Register a rule under any name and use that name in a rules: tag. Return the field-to-messages map on failure, nil, nil on success.
rules := map[string]structs.RuleFunc{
"required": structs.Required,
"oneof": structs.OneOf,
"min": func(field string, values map[string]any, def string, v reflect.Value, args []string) (map[string][]string, error) {
n, _ := utils.ToInt(values[field])
min, _ := strconv.Atoi(args[0])
if n < min {
return map[string][]string{field: {"must be at least " + args[0]}}, nil
}
return nil, nil
},
}
manager := structs.New(cfg, structs.WithRules(rules))
// field usage: `rules:"min:1"`