diff --git a/README.md b/README.md index ef811ac..cd0e75d 100644 --- a/README.md +++ b/README.md @@ -379,5951 +379,8 @@ by the validator it must implement the `valix.Constraint` interface. ### Common Constraints -Valix provides a rich set of pre-defined common constraints - listed here for reference: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ArrayConditionalConstraint
  acond (i18n tag abbr.) -
- Is a special constraint that wraps another constraint - but the wrapped - constraint is only checked when the specified array condition is met -
- Fields - - - - - - - - - - - - - -
- When string - - is the special token denoting the array condition on which the wrapped constraint is to be checked
- One of: -
    -
  • "first" array item is the first
  • -
  • "!first" array item is not the first
  • -
  • "last" array item is the last
  • -
  • "!last" array item is not the last
  • -
  • "%n" modulus n of the array index is zero
  • -
  • ">n" array index is greater than n
  • -
  • "<n" array index is less than n
  • -
  • "n" array index is n
  • -
-
- Constraint Constraint - - is the wrapped constraint -
- Ancestry uint - - is ancestry depth at which to obtain the current array index information

- Note: the ancestry level is only for arrays in the object tree (and does not need to include other levels). - Therefore, by default the value is 0 (zero) - which means the last encountered array -
-
-
- ArrayDistinctProperty
  adistinctp (i18n tag abbr.) -
- Check each object element in an array has a specified property that is distinct -
- Fields - - - - - - - - - - - - - - - - - - - - - -
- PropertyName string - - the name of the property (in each array element object) to check for distinct (uniqueness) -
- IgnoreNulls bool - - whether to ignore null items in the array -
- IgnoreCase bool - - whether uniqueness is case in-insensitive (for string elements) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- ArrayOf
  aof (i18n tag abbr.) -
- Check each element in an array value is of the correct type -
- Fields - - - - - - - - - - - - - - - - - - - - - -
- Type string - - the type to check for each item -
- AllowNullElement bool - - whether to allow null items in the array -
- Constraints []Constraint - - is an optional slice of constraints tha each array element must satisfy -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- ArrayUnique
  aunique (i18n tag abbr.) -
- Check each element in an array value is unique -
- Fields - - - - - - - - - - - - - - - - - -
- IgnoreNulls bool - - whether to ignore null items in the array -
- IgnoreCase bool - - whether uniqueness is case in-insensitive (for string elements) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- ConditionalConstraint
  cond (i18n tag abbr.) -
- Is a special constraint that wraps another constraint - but the wrapped constraint is only checked when the specified when conditions are met -
- Fields - - - - - - - - - - - - - -
- When []string - - is the condition tokens that determine when the wrapped constraint is checked -
- Others OthersExpr - - is the others expression to be evaluated to determine when the wrapped constraint is checked -
- Constraint Constraint - - is the wrapped constraint -
-
- Note: Even though this constraint has a v8n tag, it is better to use the conditional abbreviation by prefixing them with [condition,...] - (see Validation Tags ) -
- Example -
type Example struct {
-  Foo string `v8n:"&[bar,baz]StringNotEmpty{}"`
-}
- Makes the &StringNotEmpty{} constraint only checked when either bar or baz condition tokens have been set -
-
- ConstraintSet
  set (i18n tag abbr.) -
- Is a special constraint that contains other constraints
- The contained constraints are checked sequentially but the overall set stops on the first failing constraint -
- Fields - - - - - - - - - - - - - - - - - -
- Constraints []Constraint - - is the slice of constraints within the set -
- OneOf bool - - when set to true, specifies that the constraint set should pass just one of the contained constraints (rather than all of them) -
- Message string - - is the violation message to be used if any of the constraints fail
- If the message is empty, the message from the first failing contained constraint is used -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint set fails -
-
-
- DatetimeDayOfWeek
  dtdow (i18n tag abbr.) -
- Checks that a date (represented as string or time.Time) is an allowed day of the week -
- Fields - - - - - - - - - - - - - -
- Value string - - is the allowed days (of the week) expressed as a string of allowed week day numbers (in any order)
- Where 0 = Sunday, e.g. "06" (or "60") allows Sunday or Saturday
- or to allow only 'working days' of the week - "12345" -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeGreaterThan
  dtgt (i18n tag abbr.) -
- Check that a date/time (as an ISO string) value is greater than a specified value -
- Fields - - - - - - - - - - - - - - - - - -
- Value string - - the value to compare against (a string representation of date or datetime in ISO format) -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeGreaterThanOther
  dtgto (i18n tag abbr.) -
- Check that a date/time (as an ISO string) value is greater than another named property value -
- Fields - - - - - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeGreaterThanOrEqual
  dtgte (i18n tag abbr.) -
- Check that a date/time (as an ISO string) value is greater than or equal to a specified value -
- Fields - - - - - - - - - - - - - - - - - -
- Value string - - the value to compare against (a string representation of date or datetime in ISO format) -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeGreaterThanOrEqualOther
  dtgteo (i18n tag abbr.) -
- Check that a date/time (as an ISO string) value is greater than or equal to another named property value -
- Fields - - - - - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeLessThan
  dtlt (i18n tag abbr.) -
- Check that a date/time (as an ISO string) value is less than a specified value -
- Fields - - - - - - - - - - - - - - - - - -
- Value string - - the value to compare against (a string representation of date or datetime in ISO format) -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeLessThanOther
  dtlto (i18n tag abbr.) -
- Check that a date/time (as an ISO string) value is less than another named property value -
- Fields - - - - - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeLessThanOrEqual
  dtlte (i18n tag abbr.) -
- Check that a date/time (as an ISO string) value is less than or equal to a specified value -
- Fields - - - - - - - - - - - - - - - - - -
- Value string - - the value to compare against (a string representation of date or datetime in ISO format) -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeLessThanOrEqualOther
  dtlteo (i18n tag abbr.) -
- Check that a date/time (as an ISO string) value is less than or equal to another named property value -
- Fields - - - - - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeFuture
  dtfuture (i18n tag abbr.) -
- Check that a datetime/date (represented as string or time.Time) is in the future -
- Fields - - - - - - - - - - - - - -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeFutureOrPresent
  dtfuturep (i18n tag abbr.) -
- Check that a datetime/date (represented as string or time.Time) is in the future or present -
- Fields - - - - - - - - - - - - - -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimePast
  dtpast (i18n tag abbr.) -
- Check that a datetime/date (represented as string or time.Time) is in the past -
- Fields - - - - - - - - - - - - - -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimePastOrPresent
  dtpastp (i18n tag abbr.) -
- Check that a datetime/date (represented as string or time.Time) is in the past or present -
- Fields - - - - - - - - - - - - - -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeRange
  dtrange (i18n tag abbr.) -
- Check that a datetime/date (represented as string or time.Time) is within a specified range -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Minimum string - - is the minimum datetime/date (if this is empty, then no minimum check is performed) -
- Maximum string - - is the maximum datetime/date (if this is empty, then no maximum check is performed) -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- ExclusiveMin bool - - if set to true, ExclusiveMin specifies the minimum value is exclusive -
- ExclusiveMax bool - - if set to true, ExclusiveMax specifies the maximum value is exclusive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeTimeOfDayRange
  dttodrange (i18n tag abbr.) -
- Check that a datetime (represented as string or time.Time) is within a specified time of day range -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - -
- Minimum string - - is the minimum time of day (if this is empty, then no minimum check is performed)
- The time of day is specified in the format "hh:mm:ss[.nnnnnnnnn]" - but can be abbreviated, for example specifying "17" is equivalent to specifying "17:00:00 -
- Maximum string - - is the maximum time of day (if this is empty, then no maximum check is performed) -
- ExclusiveMin bool - - if set to true, ExclusiveMin specifies the minimum value is exclusive -
- ExclusiveMax bool - - if set to true, ExclusiveMax specifies the maximum value is exclusive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeTolerance
  dttol (i18n tag abbr.) -
- Check that a date/time (as an ISO string) value meets a tolerance against a specified value -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Value string - - the value to compare against (a string representation of date or datetime in ISO format) -
- Duration int64 - - the tolerance duration amount - which can be positive, negative or zero -
    -
  • - For negative values, this is the maximum duration into the past -
  • -
  • - For positive values, this is the maximum duration into the future -
  • -
  • - If the value is zero then the behaviour is assumed to be "same" - but is then dependent on the unit - specified. For example, if the Duration is zero and the Unit is specified as "year" then this constraint - will check the same year -
  • -
-
- Unit string - - is the string token specifying the unit in which the Duration is measured
- The value can - "millennium", "century", "decade", "year", "month", "week", "day", - "hour", "min"|"minute", "sec"|"second", "milli"|"millisecond", "micro"|"microsecond" or "nano"|"nanosecond"
- if this is empty, then "day" is assumed. If the token is invalid - this constraint will fail any comparisons -
- MinCheck bool - - when set to true, specifies that the tolerance is a minimum check (rather than the default maximum check) -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- IgnoreNull bool - - when set to true, IgnoreNull makes the constraint less strict by ignoring null values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeToleranceToNow
  dttolnow (i18n tag abbr.) -
- Check that a date/time (as an ISO string) value meets a tolerance against the current time -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Duration int64 - - the tolerance duration amount - which can be positive, negative or zero -
    -
  • - For negative values, this is the maximum duration into the past -
  • -
  • - For positive values, this is the maximum duration into the future -
  • -
  • - If the value is zero then the behaviour is assumed to be "same" - but is then dependent on the unit - specified. For example, if the Duration is zero and the Unit is specified as "year" then this constraint - will check the same year -
  • -
-
- Unit string - - is the string token specifying the unit in which the Duration is measured
- The value can - "millennium", "century", "decade", "year", "month", "week", "day", - "hour", "min"|"minute", "sec"|"second", "milli"|"millisecond", "micro"|"microsecond" or "nano"|"nanosecond"
- if this is empty, then "day" is assumed. If the token is invalid - this constraint will fail any comparisons -
- MinCheck bool - - when set to true, specifies that the tolerance is a minimum check (rather than the default maximum check) -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- IgnoreNull bool - - when set to true, IgnoreNull makes the constraint less strict by ignoring null values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeToleranceToOther
  dttolother (i18n tag abbr.) -
- Check that a date/time (as an ISO string) value meets a tolerance against the value of another named property value -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- Duration int64 - - the tolerance duration amount - which can be positive, negative or zero -
    -
  • - For negative values, this is the maximum duration into the past -
  • -
  • - For positive values, this is the maximum duration into the future -
  • -
  • - If the value is zero then the behaviour is assumed to be "same" - but is then dependent on the unit - specified. For example, if the Duration is zero and the Unit is specified as "year" then this constraint - will check the same year -
  • -
-
- Unit string - - is the string token specifying the unit in which the Duration is measured
- The value can - "millennium", "century", "decade", "year", "month", "week", "day", - "hour", "min"|"minute", "sec"|"second", "milli"|"millisecond", "micro"|"microsecond" or "nano"|"nanosecond"
- if this is empty, then "day" is assumed. If the token is invalid - this constraint will fail any comparisons -
- MinCheck bool - - when set to true, specifies that the tolerance is a minimum check (rather than the default maximum check) -
- ExcTime bool - - when set to true, excludes the time when comparing
- Note: This also excludes the effect of any timezone offsets specified in either of the compared values -
- IgnoreNull bool - - when set to true, IgnoreNull makes the constraint less strict by ignoring null values -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- DatetimeYearsOld
  age (i18n tag abbr.) -
- Check that a date (datetime represented as string or time.Time) meets the specified minimum and/or maximum years-old. Can also be used to simply check a minimum age or maximum age -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Minimum int - - is the minimum age (not checked if this value is zero or less) -
- Maximum int - - is the maximum age (not checked if this value is zero or less) -
- ExclusiveMin bool - - if set to true, ExclusiveMin specifies the minimum value is exclusive -
- ExclusiveMax string - - if set to true, ExclusiveMax specifies the maximum value is exclusive -
- ThisYear bool - - if set to true, only checks the minimum/maximum age against the current year - i.e. the current age is calculated based on 23:59:59.999999999 at 31st December of the current year -
- ThresholdDate string - - is an optional string representing a threshold date at which the age is calculated
- If this is specified, the year part is ignored (the current year is always used)

- Note: if specified, this also overrides the ThisYear flag -
- LeapdayAdjust bool - - if set, adjusts the way leapday birthdays are age calculated
- By default, leapday birthdays are taken as 1st March when the current year is not a leap year. - Setting LeapdayAdjust to true means that leapday birthdays are taken as 28th Feb -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- EqualsOther
  eqo (i18n tag abbr.) -
- Check that a property value equals the value of another named property -
- Fields - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- FailingConstraint
  fail (i18n tag abbr.) -
- Is a utility constraint that always fails -
- Fields - - - - - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- StopAll bool - - when set to true, StopAll stops the entire validation -
-
-
- FailWhen
  failw (i18n tag abbr.) -
- Is a utility constraint that fails when specified conditions are met -
- Fields - - - - - - - - - - - - - - - - - -
- Conditions []string - - the conditions under which to fail -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- StopAll bool - - when set to true, StopAll stops the entire validation -
-
-
- FailWith
  failwith (i18n tag abbr.) -
- Is a utility constraint that fails when specified others property expression evaluates to true -
- Fields - - - - - - - - - - - - - - - - - -
- Others OthersExpr - - is the others expression to be evaluated to determine whether the constraint should fail -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- StopAll bool - - when set to true, StopAll stops the entire validation -
-
-
- GreaterThan
  gt (i18n tag abbr.) -
- Check that a numeric value is greater than a specified value -
- Fields - - - - - - - - - - - - - -
- Value float64 - - the value to compare against -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- GreaterThanOrEqual
  gte (i18n tag abbr.) -
- Check that a numeric value is greater than or equal to a specified value -
- Fields - - - - - - - - - - - - - -
- Value float64 - - the value to compare against -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- GreaterThanOther
  gto (i18n tag abbr.) -
- Check that a numeric value is greater than another named property value -
- Fields - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- GreaterThanOrEqualOther
  gteo (i18n tag abbr.) -
- check that a numeric value is greater than or equal to another named property value -
- Fields - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- Length
  len (i18n tag abbr.) -
- Check that a value (object, array, string) has minimum and maximum length
- (Although this constraint can be used on string properties - it is advised to use StringLength instead) -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - -
- Minimum int - - the minimum length -
- Maximum int - - the maximum length (only checked if this value is > 0) -
- ExclusiveMin bool - - if set to true, ExclusiveMin specifies the minimum value is exclusive -
- ExclusiveMax string - - if set to true, ExclusiveMax specifies the maximum value is exclusive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- LengthExact
  lenx (i18n tag abbr.) -
- Check that a value (object, array, string) has a specific length
- (Although this constraint can be used on string properties - it is advised to use StringExactLength instead) -
- Fields - - - - - - - - - - - - - -
- Value int - - the length to check -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- LessThan
  lt (i18n tag abbr.) -
- Check that a numeric value is less than a specified value -
- Fields - - - - - - - - - - - - - -
- Value float64 - - the value to compare against -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- LessThanOrEqual
  lte (i18n tag abbr.) -
- Check that a numeric value is less than or equal to a specified value -
- Fields - - - - - - - - - - - - - -
- Value float64 - - the value to compare against -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- LessThanOther
  lto (i18n tag abbr.) -
- Check that a numeric value is less than another named property value -
- Fields - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- LessThanOrEqualOther
  lteo (i18n tag abbr.) -
- Check that a numeric value is less than or equal to another named property value -
- Fields - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- Maximum
  max (i18n tag abbr.) -
- Check that a numeric value is less than or equal to a specified maximum -
- Fields - - - - - - - - - - - - - - - - - - - - - -
- Value float64 - - the maximum value -
- ExclusiveMax bool - - if set to true, ExclusiveMax specifies the maximum value is exclusive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- MaximumInt
  maxi (i18n tag abbr.) -
- Check that an integer value is less than or equal to a specified maximum -
- Fields - - - - - - - - - - - - - - - - - - - - - -
- Value int64 - - the maximum value -
- ExclusiveMax bool - - if set to true, ExclusiveMax specifies the maximum value is exclusive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- Minimum
  min (i18n tag abbr.) -
- Check that a numeric value is greater than or equal to a specified minimum -
- Fields - - - - - - - - - - - - - - - - - - - - - -
- Value float64 - - the minimum value -
- ExclusiveMin bool - - if set to true, ExclusiveMin specifies the minimum value is exclusive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- MinimumInt
  mini (i18n tag abbr.) -
- Check that an integer value is greater than or equal to a specified minimum -
- Fields - - - - - - - - - - - - - - - - - - - - - -
- Value int64 - - the minimum value -
- ExclusiveMin bool - - if set to true, ExclusiveMin specifies the minimum value is exclusive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- MultipleOf
  xof (i18n tag abbr.) -
- Check that an integer value is a multiple of a specific number -
- Fields - - - - - - - - - - - - - - - - - -
- Value int64 - - the multiple of value to check -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- Negative
  neg (i18n tag abbr.) -
- Check that a numeric value is negative -
- Fields - - - - - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- NegativeOrZero
  negz (i18n tag abbr.) -
- Check that a numeric value is negative or zero -
- Fields - - - - - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- NetIsCIDR
  isCIDR (i18n tag abbr.) -
- Check that string value is a valid CIDR (v4 or v6) address -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - -
- V4Only bool - - if set, allows only CIDR v4 -
- V6Only bool - - if set, allows only CIDR v6 -
- DisallowLoopback bool - - if set, disallows loopback addresses -
- DisallowPrivate bool - - if set, disallows private addresses -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- NetIsHostname
  isHostname (i18n tag abbr.) -
- Check that string value is a valid hostname -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- AllowIPAddress bool - - when set, allows IP address hostnames -
- AllowIPV6 bool - - when set, allows IP v6 address hostnames -
- AllowLocal bool - - when set, allows hostnames 'local' (e.g. "localhost", "local", "localdomain", "127.0.0.1", "::1") -
- AllowTldOnly bool - - when set, allows hostnames with only Tld specified (e.g. "audi") -
- AllowGeographicTlds bool - - when set, allows hostnames with geographic Tlds (e.g. "some-company.africa") -
- AllowGenericTlds bool - - when set, allows hostnames with generic Tlds (e.g. "some.academy") -
- AllowBrandTlds bool - - when set, allows hostnames with brand Tlds (e.g. "my.audi") -
- AllowInfraTlds bool - - when set, allows hostnames with infrastructure Tlds (e.g. "arpa") -
- AllowTestTlds bool - - when set, allows hostnames with test Tlds and test domains (e.g. "example.com", "test.com") -
- AddCountryCodeTlds []string - - is an optional slice of additional country (and geographic) Tlds to allow -
- ExcCountryCodeTlds []string - - is an optional slice of country (and geographic) Tlds to disallow -
- AddGenericTlds []string - - is an optional slice of additional generic Tlds to allow (only checked if AllowGenericTlds is also set) -
- ExcGenericTlds []string - - is an optional slice of generic Tlds to disallow (only relevant if AllowGenericTlds is also set) -
- AddBrandTlds []string - - is an optional slice of additional brand Tlds to allow (only checked if AllowBrandTlds is also set) -
- ExcBrandTlds []string - - is an optional slice of brand Tlds to disallow (only relevant if AllowBrandTlds is also set) -
- AddLocalTlds []string - - is an optional slice of additional local Tlds to allow (only checked if AllowLocal is also set) -
- ExcLocalTlds []string - - is an optional slice of local Tlds to disallow (only relevant if AllowLocal is also set) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- NetIsIP
  isIP (i18n tag abbr.) -
- Check that string value is a valid IP (v4 or v6) address -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- V4Only bool - - if set, allows only IP v4 -
- V6Only bool - - if set, allows only IP v6 -
- Resolvable bool - - if set, checks that the address is resolvable -
- DisallowLoopback bool - - if set, disallows loopback addresses -
- DisallowPrivate bool - - if set, disallows private addresses -
- AllowLocalhost bool - - if set, allows value of "localhost" to be seen as valid -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- NetIsMac
  isMAC (i18n tag abbr.) -
- Check that string value is a valid MAC address -
- Fields - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- NetIsTCP
  isTCP (i18n tag abbr.) -
- Check that string value is a valid resolvable TCP (v4 or v6) address -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - -
- V4Only bool - - if set, allows only TCP v4 -
- V6Only bool - - if set, allows only TCP v6 -
- DisallowLoopback bool - - if set, disallows loopback addresses -
- DisallowPrivate bool - - if set, disallows private addresses -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- NetIsTld
  isTld (i18n tag abbr.) -
- Check that string value is a valid Tld (top level domain) -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- AllowGeographicTlds bool - - when set, allows geogrpahic tlds to be seen as valid -
- AllowGenericTlds bool - - when set, allows generic tlds to be seen as valid -
- AllowBrandTlds bool - - when set, allows brand tlds to be seen as valid -
- AddCountryCodeTlds []string - - additional country (or geographic) tlds to be seen as valid -
- ExcCountryCodeTlds []string - - excludes specific country (or geographic) tlds being seen as valid -
- AddGenericTlds []string - - additional generic tlds to be seen as valid -
- ExcGenericTlds []string - - excludes specific generic tlds being seen as valid -
- AddBrandTlds []string - - additional brand tlds to be seen as valid -
- ExcBrandTlds []string - - excludes specific brand tlds being seen as valid -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- NetIsUDP
  isUDP (i18n tag abbr.) -
- Check that string value is a valid resolvable UDP (v4 or v6) address -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - -
- V4Only bool - - if set, allows only UDP v4 -
- V6Only bool - - if set, allows only UDP v6 -
- DisallowLoopback bool - - if set, disallows loopback addresses -
- DisallowPrivate bool - - if set, disallows private addresses -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- NetIsURI
  isURI (i18n tag abbr.) -
- Check that string value is a valid URI -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- CheckHost bool - - if set, the host is also checked (see also AllowIPAddress and others) -
- AllowIPAddress bool - - when set, allows IP address hostnames -
- AllowIPV6 bool - - when set, allows IP v6 address hostnames -
- AllowLocal bool - - when set, allows hostnames 'local' (e.g. "localhost", "local", "localdomain", "127.0.0.1", "::1") -
- AllowTldOnly bool - - when set, allows hostnames with only Tld specified (e.g. "audi") -
- AllowGeographicTlds bool - - when set, allows hostnames with geographic Tlds (e.g. "some-company.africa") -
- AllowGenericTlds bool - - when set, allows hostnames with generic Tlds (e.g. "some.academy") -
- AllowBrandTlds bool - - when set, allows hostnames with brand Tlds (e.g. "my.audi") -
- AllowInfraTlds bool - - when set, allows hostnames with infrastructure Tlds (e.g. "arpa") -
- AllowTestTlds bool - - when set, allows hostnames with test Tlds and test domains (e.g. "example.com", "test.com") -
- AddCountryCodeTlds []string - - is an optional slice of additional country (and geographic) Tlds to allow -
- ExcCountryCodeTlds []string - - is an optional slice of country (and geographic) Tlds to disallow -
- AddGenericTlds []string - - is an optional slice of additional generic Tlds to allow (only checked if AllowGenericTlds is also set) -
- ExcGenericTlds []string - - is an optional slice of generic Tlds to disallow (only relevant if AllowGenericTlds is also set) -
- AddBrandTlds []string - - is an optional slice of additional brand Tlds to allow (only checked if AllowBrandTlds is also set) -
- ExcBrandTlds []string - - is an optional slice of brand Tlds to disallow (only relevant if AllowBrandTlds is also set) -
- AddLocalTlds []string - - is an optional slice of additional local Tlds to allow (only checked if AllowLocal is also set) -
- ExcLocalTlds []string - - is an optional slice of local Tlds to disallow (only relevant if AllowLocal is also set) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- NetIsURL
  isURL (i18n tag abbr.) -
- Check that string value is a valid URL -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- CheckHost bool - - if set, the host is also checked (see also AllowIPAddress and others) -
- AllowIPAddress bool - - when set, allows IP address hostnames -
- AllowIPV6 bool - - when set, allows IP v6 address hostnames -
- AllowLocal bool - - when set, allows hostnames 'local' (e.g. "localhost", "local", "localdomain", "127.0.0.1", "::1") -
- AllowTldOnly bool - - when set, allows hostnames with only Tld specified (e.g. "audi") -
- AllowGeographicTlds bool - - when set, allows hostnames with geographic Tlds (e.g. "some-company.africa") -
- AllowGenericTlds bool - - when set, allows hostnames with generic Tlds (e.g. "some.academy") -
- AllowBrandTlds bool - - when set, allows hostnames with brand Tlds (e.g. "my.audi") -
- AllowInfraTlds bool - - when set, allows hostnames with infrastructure Tlds (e.g. "arpa") -
- AllowTestTlds bool - - when set, allows hostnames with test Tlds and test domains (e.g. "example.com", "test.com") -
- AddCountryCodeTlds []string - - is an optional slice of additional country (and geographic) Tlds to allow -
- ExcCountryCodeTlds []string - - is an optional slice of country (and geographic) Tlds to disallow -
- AddGenericTlds []string - - is an optional slice of additional generic Tlds to allow (only checked if AllowGenericTlds is also set) -
- ExcGenericTlds []string - - is an optional slice of generic Tlds to disallow (only relevant if AllowGenericTlds is also set) -
- AddBrandTlds []string - - is an optional slice of additional brand Tlds to allow (only checked if AllowBrandTlds is also set) -
- ExcBrandTlds []string - - is an optional slice of brand Tlds to disallow (only relevant if AllowBrandTlds is also set) -
- AddLocalTlds []string - - is an optional slice of additional local Tlds to allow (only checked if AllowLocal is also set) -
- ExcLocalTlds []string - - is an optional slice of local Tlds to disallow (only relevant if AllowLocal is also set) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- NotEmpty
  notempty (i18n tag abbr.) -
- Check that a map or slice property value is not empty (has properties or array elements) -
- Fields - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- NotEqualsOther
  neqo (i18n tag abbr.) -
- Check that a property value not equals the value of another named property -
- Fields - - - - - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the other property is not present (even though the not equals would technically be ok) -
-
-
- Positive
  pos (i18n tag abbr.) -
- Check that a numeric value is positive (exc. zero) -
- Fields - - - - - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- PositiveOrZero
  posz (i18n tag abbr.) -
- Check that a numeric value is positive or zero -
- Fields - - - - - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- Range
  range (i18n tag abbr.) -
- Check that a numeric value is within a specified minimum and maximum range -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Minimum float64 - - the minimum value of the range -
- Maximum float64 - - the maximum value of the range -
- ExclusiveMin bool - - if set to true, ExclusiveMin specifies the minimum value is exclusive -
- ExclusiveMax string - - if set to true, ExclusiveMax specifies the maximum value is exclusive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- RangeInt
  rangei (i18n tag abbr.) -
- Check that an integer value is within a specified minimum and maximum range -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Minimum int64 - - the minimum value of the range -
- Maximum int64 - - the maximum value of the range -
- ExclusiveMin bool - - if set to true, ExclusiveMin specifies the minimum value is exclusive -
- ExclusiveMax string - - if set to true, ExclusiveMax specifies the maximum value is exclusive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- SetConditionFrom
  cfrom (i18n tag abbr.) -
- Is a utility constraint that can be used to set a condition in the ValidatorContext from the value of - the property to which this constraint is added.
- (see example usage in Conditional Constraints) -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - -
- Parent bool - - by default, conditions are set on the current property or object - but specifying true for this field means the condition is set on the parent object too -
- Global bool - - setting this field to true means the condition is set for the entire validator context -
- Prefix string - - is any prefix to be appended to the condition token -
- Mapping map[string]string - - converts the string value to alternate values (if the value is not found in the map then the original value is used -
- NullToken string - - is the condition token used if the value of the property is null/nil. If this field is not set - and the property value is null at validation - then a condition token of "null" is used -
- Format string - - is an optional format string for dealing with non-string property values -
-
-
- SetConditionIf
  cif (i18n tag abbr.) -
- Is a special constraint that wraps another constraint and sets a condition based on whether that wrapped constraint is ok or fails
- Note: the wrapped constraint cannot add any violations and cannot stop the validation (i.e. it is called 'silently') -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Constraint Constraint - - is the wrapped constraint to be checked
- If this is nil, the SetOk condition is always set
- Note: the wrapped constraint cannot add any violations and cannot stop the validation (i.e. it is called 'silently') -
- SetOk string - - is the condition to set if the wrapped constraint is ok
- Note: if this is an empty string - no condition is set -
- SetFail string - - is the condition to set if the wrapped constraint fails
- Note: if this is an empty string - no condition is set -
- Parent bool - - by default, conditions are set on the current property or object - but specifying true for this field means the condition is set on the parent object too -
- Global bool - - setting this field to true means the condition is set for the entire validator context -
- Prefix string - - is any prefix to be appended to the condition token -
- Mapping map[string]string - - converts the string value to alternate values (if the value is not found in the map then the original value is used -
- NullToken string - - is the condition token used if the value of the property is null/nil. If this field is not set - and the property value is null at validation - then a condition token of "null" is used -
- Format string - - is an optional format string for dealing with non-string property values -
-
-
- SetConditionOnType
  ctype (i18n tag abbr.) -
- Is a utility constraint that can be used to set a condition in the - ValidatorContext indicating the type of the property value to which this constraint is added. -
- Fields - None -
-
- SetConditionProperty
  cpty (i18n tag abbr.) -
- Is a utility constraint that can be used to set a condition in the ValidatorContext from the value of a specified property - within the object to which this constraint is attached
- (see example usage in Polymorphic Validation) -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - -
- PropertyName string - - the name of the property to extract the condition value from -
- Prefix string - - is any prefix to be appended to the condition token -
- Mapping map[string]string - - converts the token value to alternate values (if the value is not found in the map then the original value is used -
- NullToken string - - is the condition token used if the value of the property specified is null/nil. If this field is not set - and the property value is null at validation - then a condition token of "null" is used -
- MissingToken string - - is the condition token used if the property specified is missing. If this field is not set - and the property is missing at validation - then a condition token of "missing" is used -
- Format string - - is an optional format string for dealing with non-string property values -
-
-
- StringCharacters
  strchars (i18n tag abbr.) -
- Check that a string contains only allowable characters (and does not contain any disallowed characters) -
- Fields - - - - - - - - - - - - - - - - - - - - - -
- AllowRanges []unicode.RangeTable - - the ranges of characters (runes) that are allowed - each character must be in at least one of these -
- DisallowRanges []unicode.RangeTable - - the ranges of characters (runes) that are not allowed - if any character is in any of these ranges then the constraint is violated -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringContains
  contains (i18n tag abbr.) -
- Check that a string contains with a given value -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Value string - - the value to check that the string contains -
- Values []string - - multiple additional values that the string may contain -
- CaseInsensitive bool - - whether the check is case-insensitive (by default, the check is case-sensitive) -
- Not bool - - whether the check is NOT-ed (i.e. checks that the string does not contain) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringEndsWith
  ends (i18n tag abbr.) -
- Check that a string ends with a given suffix -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Value string - - the value to check that the string ends with -
- Values []string - - multiple additional values that the string may end with -
- CaseInsensitive bool - - whether the check is case-insensitive (by default, the check is case-sensitive) -
- Not bool - - whether the check is NOT-ed (i.e. checks that the string does not end with) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringLength
  strlen (i18n tag abbr.) -
- Check that a string has a minimum and maximum length -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Minimum int - - the minimum length -
- Maximum int - - the maximum length (only checked if this value is > 0) -
- ExclusiveMin bool - - if set to true, ExclusiveMin specifies the minimum value is exclusive -
- ExclusiveMax string - - if set to true, ExclusiveMax specifies the maximum value is exclusive -
- UseRuneLen bool - - if set to true, uses the rune length (true Unicode length) to check length of string -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringExactLength
  strxlen (i18n tag abbr.) -
- Check that a string has an exact length -
- Fields - - - - - - - - - - - - - - - - - - - - - -
- Value int - - the exact length expected -
- UseRuneLen bool - - if set to true, uses the rune length (true Unicode length) to check length of string -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringGreaterThan
  strgt (i18n tag abbr.) -
- Check that a string value is greater than a specified value -
- Fields - - - - - - - - - - - - - - - - - -
- Value string - - the value to compare against -
- CaseInsensitive bool - - when set, the comparison is case-insensitive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- StringGreaterThanOrEqual
  strgte (i18n tag abbr.) -
- Check that a string value is greater than or equal to a specified value -
- Fields - - - - - - - - - - - - - - - - - -
- Value string - - the value to compare against -
- CaseInsensitive bool - - when set, the comparison is case-insensitive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- StringGreaterThanOther
  strgto (i18n tag abbr.) -
- Check that a string value is greater than another named property value -
- Fields - - - - - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- CaseInsensitive bool - - when set, the comparison is case-insensitive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- StringGreaterThanOrEqualOther
  strgteo (i18n tag abbr.) -
- Check that a string value is greater than or equal to another named property value -
- Fields - - - - - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- CaseInsensitive bool - - when set, the comparison is case-insensitive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- StringLessThan
  strlt (i18n tag abbr.) -
- Check that a string value is less than a specified value -
- Fields - - - - - - - - - - - - - - - - - -
- Value string - - the value to compare against -
- CaseInsensitive bool - - when set, the comparison is case-insensitive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- StringLessThanOrEqual
  strlte (i18n tag abbr.) -
- Check that a string value is less than or equal to a specified value -
- Fields - - - - - - - - - - - - - - - - - -
- Value string - - the value to compare against -
- CaseInsensitive bool - - when set, the comparison is case-insensitive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- StringLessThanOther
  strlto (i18n tag abbr.) -
- Check that a string value is less than another named property value -
- Fields - - - - - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- CaseInsensitive bool - - when set, the comparison is case-insensitive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- StringLessThanOrEqualOther
  strlteo (i18n tag abbr.) -
- Check that a string value is less than or equal to another named property value -
- Fields - - - - - - - - - - - - - - - - - -
- PropertyName string - - the property name of the other value to compare against

- Note: the PropertyName can also be JSON dot notation path - where leading dots allow traversal up - the object tree and names, separated by dots, allow traversal down the object tree.
- A single dot at start is equivalent to no starting dot (i.e. a property name at the same level) -
- CaseInsensitive bool - - when set, the comparison is case-insensitive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- StringLowercase
  strlower (i18n tag abbr.) -
- Check that a string has only lowercase letters -
- Fields - - - - - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringMaxLength
  strmax (i18n tag abbr.) -
- Check that a string has a maximum length -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - -
- Value int - - the maximum length value -
- ExclusiveMax bool - - if set to true, ExclusiveMax specifies the maximum value is exclusive -
- UseRuneLen bool - - if set to true, uses the rune length (true Unicode length) to check length of string -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringMinLength
  strmin (i18n tag abbr.) -
- Check that a string has a minimum length -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - -
- Value int - - the minimum length value -
- ExclusiveMin bool - - if set to true, ExclusiveMin specifies the minimum value is exclusive -
- UseRuneLen bool - - if set to true, uses the rune length (true Unicode length) to check length of string -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringNotBlank
  strnb (i18n tag abbr.) -
- Check that string value is not blank (i.e. that after removing leading and trailing whitespace the value is - not an empty string) -
- Fields - - - - - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringNotEmpty
  strne (i18n tag abbr.) -
- Check that string value is not empty (i.e. not "") -
- Fields - - - - - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringNoControlCharacters
  strnocc (i18n tag abbr.) -
- Check that a string does not contain any control characters (i.e. chars < 32) -
- Fields - - - - - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringPattern
  strpatt (i18n tag abbr.) -
- Check that a string matches a given regexp pattern -
- Fields - - - - - - - - - - - - - - - - - -
- Regexp regexp.Regexp - - the regexp pattern that the string value must match -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringPresetPattern
  strpreset (i18n tag abbr.) -
- Check that a string matches a given preset pattern
- There are Preset patterns are defined in the PatternPresets variable (add your own where required) and - messages for the preset patterns are defined in the PatternPresetMessages
- If the preset pattern requires some extra validation beyond the regexp match, then add a checker to the PatternPresetPostPatternChecks variable -
- Fields - - - - - - - - - - - - - - - - - -
- Preset string - - the preset token (which must exist in the PatternPresets map)
- If the specified preset token does not exist - the constraint fails! -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
- There are 40+ built-in preset patterns (listed below) - and you can add your own using the valix.RegisterPresetPattern() function. -
- List of built-in presets - Note: Post check indicates whether value is further checked after regexp match - for example, check digits on card numbers & barcodes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
tokenmessage / descriptionpost check?
alphaValue must be only alphabet characters (A-Z, a-z)
alphaNumericValue must be only alphanumeric characters (A-Z, a-z, 0-9)
barcode - Value must be a valid barcode
- Checks against EAN, ISBN, ISSN, UPC regexps and verifies using check digit -
base64Value must be a valid base64 encoded string
base64URLValue must be a valid base64 URL encoded string
cardValue must be a valid card number
cmyk - Value must be a valid cmyk() color string
- (components as 0.162 or 16.2%) -
cmyk300 - Value must be a valid cmyk() color string (maximum 300%)
- Post-check ensures components do not exceed 300%
- (components as 0.162 or 16.2%) -
EAN - Value must be a valid EAN code
- (EAN-8, 13, 14, 18 or 99) -
EAN8Value must be a valid EAN-8 code
EAN13Value must be a valid EAN-13 code
DUN14Value must be a valid DUN-14 code
EAN14Value must be a valid EAN-14 code
EAN18Value must be a valid EAN-18 code
EAN99Value must be a valid EAN-99 code
e164Value must be a valid E.164 code
hexadecimalValue must be a valid hexadecimal string
hslValue must be a valid hsl() color string
hslaValue must be a valid hsla() color string
htmlColorValue must be a valid HTML color string
integerValue must be a valid integer string (characters 0-9)
ISBNValue must be a valid ISBN (10 or 13 digit)
ISBN10Value must be a valid ISBN (10 digit only)
ISBN13Value must be a valid ISBN (13 digit only)
ISSNValue must be a valid ISSN (8 or 13 digit)
ISSN13Value must be a valid ISSN (13 digit only)
ISSN8Value must be a valid ISSN (8 digit only)
numericValue must be a valid number string
numeric+eValue must be a valid number string
also allows scientific notation - e.g. "1.2e34"
numeric+xValue must be a valid number string
also allows scientific notation - e.g. "1.2e34", or "Inf" or "NaN"
publicationValue must be a valid ISBN or ISSN
rgbValue must be a valid rgb() color string
rgbaValue must be a valid rgba() color string
rgb-icc - Value must be a valid rgb-icc() color string
- Post-check ensures components are correct -
ULIDValue must be a valid ULID
UPCValue must be a valid UPC code (UPC-A or UPC-E)
UPC-AValue must be a valid UPC-A code
UPC-EValue must be a valid UPC-E code
uuidValue must be a valid UUID (lowercase hex chars only)
UUIDValue must be a valid UUID (upper or lower hex chars)
uuid1Value must be a valid UUID (Version 1) (lowercase hex chars only)
UUID1Value must be a valid UUID (Version 1) (upper or lower hex chars)
uuid2Value must be a valid UUID (Version 2) (lowercase hex chars only)
UUID2Value must be a valid UUID (Version 2) (upper or lower hex chars)
uuid3Value must be a valid UUID (Version 3) (lowercase hex chars only)
UUID3Value must be a valid UUID (Version 3) (upper or lower hex chars)
uuid4Value must be a valid UUID (Version 4) (lowercase hex chars only)
UUID4Value must be a valid UUID (Version 4) (upper or lower hex chars)
uuid5Value must be a valid UUID (Version 5) (lowercase hex chars only)
UUID5Value must be a valid UUID (Version 5) (upper or lower hex chars)
-
-
- StringStartsWith
  starts (i18n tag abbr.) -
- Check that a string starts with a given prefix -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Value string - - the value to check that the string starts with -
- Values []string - - multiple additional values that the string may start with -
- CaseInsensitive bool - - whether the check is case-insensitive (by default, the check is case-sensitive) -
- Not bool - - whether the check is NOT-ed (i.e. checks that the string does not start with) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringUppercase
  strupper (i18n tag abbr.) -
- Check that a string has only uppercase letters -
- Fields - - - - - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringValidCardNumber
  strvcn (i18n tag abbr.) -
- Check that a string contains a valid card number (according to Luhn Algorithm) -
- Fields - - - - - - - - - - - - - - - - - -
- AllowSpaces bool - - if set to true, accepts space separators in the card number (but must appear between each 4 digits) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringValidCountryCode
  strcountry (i18n tag abbr.) -
- Check that a string is a valid ISO-3166 (3166-1 / 3166-2) country code -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Allow3166_2 bool - - if set to true, allows ISO-3166-2 country and region codes -
- Allow3166_2_Obsoletes bool - - if set to true (along with Allow3166_2), allows ISO-3166-2 obsolete region codes -
- AllowUserAssigned bool - - if set to true, allows ISO-3166-1 user assigned country codes -
- Allow3166_1_ExceptionallyReserved bool - - if set to true, allows ISO-3166-1 exceptionally reserved country codes -
- Allow3166_1_IndeterminatelyReserved bool - - if set to true, allows ISO-3166-1 indeterminately reserved country codes -
- Allow3166_1_TransitionallyReserved bool - - if set to true, allows ISO-3166-1 transitionally reserved country codes -
- Allow3166_1_Deleted bool - - if set to true, allows ISO-3166-1 deleted country codes -
- Allow3166_1_Numeric bool - - if set to true, allows ISO-3166-1 numeric country codes
- if AllowUserAssigned is also set to true, also allows user assigned contry code (i.e 900 - 999) -
- NumericOnly bool - - if set to true, overrides all other flags (with the exception of AllowUserAssigned) and allows only ISO-3166-1 numeric codes -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- StringValidCurrencyCode
  strccy (i18n tag abbr.) -
- Check that a string is a valid ISO-4217 currency code -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- AllowNumeric bool - - if set to true, allows ISO-4217 numeric codes -
- AllowHistorical bool - - if set to true, allows historical ISO-4217 codes (and historical numeric codes - if AllowNumeric is also set) -
- AllowTestCode bool - - if set to true, allows ISO-4217 test code (XTS / 963) -
- AllowNoCode bool - - if set to true, allows ISO-4217 no currency code (XXX / 999) -
- AllowCrypto bool - - if set to true, allows commonly used crypto currency codes -
- AllowUnofficial bool - - if set to true, allows commonly used unofficial currency codes -
- NumericOnly bool - - if set to true, allows only ISO-4217 numeric currency codes -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- StringValidEmail
  stremail (i18n tag abbr.) -
- Check that a string contains a valid email address -
- Fields - - - - - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringValidISODate
  strisod (i18n tag abbr.) -
- Check that a string value is a valid ISO 8601 Date format (excluding time) -
- Fields - - - - - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringValidISODatetime
  strisodt (i18n tag abbr.) -
- Check that a string value is a valid ISO 8601 Date/time format -
- Fields - - - - - - - - - - - - - - - - - - - - - -
- NoOffset bool - - specifies, if set to true, that time offsets are not permitted -
- NoMillis bool - - specifies, if set to true, that seconds cannot have decimal places -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringValidISODuration
  strisodur (i18n tag abbr.) -
- Checks that a string value is a valid ISO 8601 Duration -
- Fields - - - - - - - - - - - - - -
- DisallowNegative bool - - if set, disallows negative durations (e.g. "-P1Y") -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- StringValidJson
  strjson (i18n tag abbr.) -
- Checks that a string is valid json -
- Fields - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- DisallowNullJson bool - - if set to true, disallows "null" as valid -
- DisallowValue bool - - if set to true, disallows single value (e.g. "true") as valid -
- DisallowArray bool - - if set to true, disallows JSON arrays as valid -
- DisallowObject bool - - if set to true, disallows JSON objects as valid -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringValidLanguageCode
  strlang (i18n tag abbr.) -
- Check that a string is a valid BCP-47 language code -
- Fields - - - - - - - - - - - - - -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringValidToken
  strtoken (i18n tag abbr.) -
- Check that a string matches one of a pre-defined list of tokens -
- Fields - - - - - - - - - - - - - - - - - - - - - -
- Tokens []string - - the set of allowed tokens for the string -
- IgnoreCase bool - - set to true to make the token check case in-sensitive -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringValidTimezone
  strtz (i18n tag abbr.) -
- Check that a string value is a valid timezone -
- Fields - - - - - - - - - - - - - - - - - - - - - -
- LocationOnly bool - - if set to true, allows location only -
- OffsetOnly bool - - if set to true, allows offset only -
- AllowNumeric bool - - if set to true, allows offset to be a numeric value (aswell as a string) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
-
-
- StringValidUnicodeNormalization
  struninorm (i18n tag abbr.) -
- Check that a string has the correct Unicode normalization form -
- Fields - - - - - - - - - - - - - - - - - -
- Form norm.Form - - the normalization form required - i.e. norm.NFC, norm.NFKC, norm.NFD or norm.NFKD -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
- StringValidUuid
  struuid (i18n tag abbr.) -
- Check that a string value is a valid UUID (and optionally of a minimum or specified version) -
- Fields - - - - - - - - - - - - - - - - - - - - - -
- MinVersion uint8 - - the minimum UUID version (optional - if zero this is not checked) -
- SpecificVersion uint8 - - the specific UUID version (optional - if zero this is not checked) -
- Message string - - the violation message to be used if the constraint fails (if empty, the default violation message is used) -
- Stop bool - - when set to true, prevents further validation checks on the property if this constraint fails -
- Strict bool - - when set to true, fails if the value being checked is not a correct type -
-
-
+Valix provides a rich set of over 100 pre-defined common constraints (plus many common regex patterns) - +see [Constraints Reference](https://github.com/marrow16/valix/wiki/Constraints-Reference) wiki documentation for full reference with examples. ### Constraint Sets diff --git a/constraint.go b/constraint.go index 54edc28..4716c7b 100644 --- a/constraint.go +++ b/constraint.go @@ -14,6 +14,22 @@ type Constraint interface { // Check function signature for custom constraints type Check func(value interface{}, vcx *ValidatorContext, this *CustomConstraint) (passed bool, message string) +type Conditional interface { + MeetsConditions(vcx *ValidatorContext) bool +} + +func isConditional(c Constraint) (Conditional, bool) { + cc, ok := c.(Conditional) + return cc, ok +} + +func isCheckRequired(c Constraint, vcx *ValidatorContext) bool { + if cc, ok := isConditional(c); ok { + return cc.MeetsConditions(vcx) + } + return true +} + // CustomConstraint is a constraint that can declared on the fly and implements the Constraint interface type CustomConstraint struct { CheckFunc Check @@ -34,102 +50,3 @@ func (c *CustomConstraint) Check(v interface{}, vcx *ValidatorContext) (bool, st func (c *CustomConstraint) GetMessage(tcx I18nContext) string { return obtainI18nContext(tcx).TranslateMessage(c.Message) } - -// ConstraintSet is a constraint that contains other constraints -// -// The contained constraints are checked sequentially but the overall -// set stops on the first failing constraint -type ConstraintSet struct { - // Constraints is the slice of constraints within the set - Constraints Constraints - // when set to true, OneOf specifies that the constraint set should pass just one of - // the contained constraints (rather than all of them) - OneOf bool - // Message is the violation message to be used if any of the constraints fail - // - // If the message is empty, the message from the first failing contained constraint is used - Message string - // Stop when set to true, prevents further validation checks on the property if this constraint set fails - Stop bool -} - -const ( - constraintSetName = "ConstraintSet" - constraintSetFieldConstraints = "Constraints" - constraintSetFieldOneOf = "OneOf" - constraintSetFieldMessage = constraintPtyNameMessage - constraintSetFieldStop = constraintPtyNameStop - fmtMsgConstraintSetDefaultAllOf = "Constraint set must pass all of %[1]d undisclosed validations" - fmtMsgConstraintSetDefaultOneOf = "Constraint set must pass one of %[1]d undisclosed validations" -) - -// Check implements the Constraint.Check and checks the constraints within the set -func (c *ConstraintSet) Check(v interface{}, vcx *ValidatorContext) (bool, string) { - if c.OneOf { - return c.checkOneOf(v, vcx) - } else { - return c.checkAllOf(v, vcx) - } -} - -func (c *ConstraintSet) checkAllOf(v interface{}, vcx *ValidatorContext) (bool, string) { - for _, cc := range c.Constraints { - if isCheckRequired(cc, vcx) { - if ok, msg := cc.Check(v, vcx); !ok { - if c.Message == "" && msg != "" { - vcx.CeaseFurtherIf(c.Stop) - return false, msg - } - vcx.CeaseFurtherIf(c.Stop) - return false, c.GetMessage(vcx) - } - if !vcx.continueAll || !vcx.continuePty() { - break - } - } - } - return true, "" -} - -func (c *ConstraintSet) checkOneOf(v interface{}, vcx *ValidatorContext) (bool, string) { - finalOk := false - firstMsg := "" - for _, cc := range c.Constraints { - if isCheckRequired(cc, vcx) { - if ok, msg := cc.Check(v, vcx); ok { - finalOk = true - break - } else if firstMsg == "" { - firstMsg = msg - } - if !vcx.continueAll || !vcx.continuePty() { - break - } - } - } - if finalOk { - return true, "" - } - vcx.CeaseFurtherIf(c.Stop) - if c.Message == "" && firstMsg != "" { - return false, firstMsg - } - return false, c.GetMessage(vcx) -} - -// GetMessage implements the Constraint.GetMessage -func (c *ConstraintSet) GetMessage(tcx I18nContext) string { - if c.Message == "" { - for _, sc := range c.Constraints { - if msg := sc.GetMessage(tcx); msg != "" { - return msg - } - } - // if we get here then the message is still empty!... - if c.OneOf { - return obtainI18nContext(tcx).TranslateFormat(fmtMsgConstraintSetDefaultOneOf, len(c.Constraints)) - } - return obtainI18nContext(tcx).TranslateFormat(fmtMsgConstraintSetDefaultAllOf, len(c.Constraints)) - } - return obtainI18nContext(tcx).TranslateMessage(c.Message) -} diff --git a/constraint_registry.go b/constraint_registry.go index 417e884..c07f250 100644 --- a/constraint_registry.go +++ b/constraint_registry.go @@ -59,6 +59,8 @@ func defaultConstraints() map[string]Constraint { "GreaterThanOrEqual": &GreaterThanOrEqual{}, "GreaterThanOrEqualOther": &GreaterThanOrEqualOther{}, "GreaterThanOther": &GreaterThanOther{}, + "IsNotNull": &IsNotNull{}, + "IsNull": &IsNull{}, "Length": &Length{}, "LengthExact": &LengthExact{}, "LessThan": &LessThan{}, @@ -189,6 +191,8 @@ func defaultConstraints() map[string]Constraint { "negz": &NegativeOrZero{}, "neqo": &NotEqualsOther{}, "notempty": &NotEmpty{}, + "notnull": &IsNotNull{}, + "null": &IsNull{}, "pos": &Positive{}, "posz": &PositiveOrZero{}, "range": &Range{}, diff --git a/constraint_registry_test.go b/constraint_registry_test.go index 05730f9..d4d0205 100644 --- a/constraint_registry_test.go +++ b/constraint_registry_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/require" ) -const commonConstraintsCount = 101 // excludes abbreviations (every constraint has an abbreviation) +const commonConstraintsCount = 103 // excludes abbreviations (every constraint has an abbreviation) const commonSpecialAbbrsCount = 8 // special abbreviations func TestConstraintsRegistryInitialized(t *testing.T) { diff --git a/constraint_test.go b/constraint_test.go index 9f37a15..ad546c6 100644 --- a/constraint_test.go +++ b/constraint_test.go @@ -1,12 +1,9 @@ package valix import ( - "fmt" + "github.com/stretchr/testify/require" "strings" "testing" - "unicode" - - "github.com/stretchr/testify/require" ) func TestCanCreateCustomConstraint(t *testing.T) { @@ -58,309 +55,14 @@ func TestCustomConstraint(t *testing.T) { require.True(t, ok) } -func TestConstraintSet(t *testing.T) { - const msg = "String value length must be between 16 and 64 chars; must be letters (upper or lower), digits or underscores; must start with an uppercase letter" - set := &ConstraintSet{ - Constraints: Constraints{ - &StringNotEmpty{}, - &StringLength{Minimum: 16, Maximum: 64}, - NewCustomConstraint(func(value interface{}, vcx *ValidatorContext, this *CustomConstraint) (bool, string) { - if str, ok := value.(string); ok { - if len(str) == 0 || str[0] < 'A' || str[0] > 'Z' { - return false, this.GetMessage(vcx) - } - } - return true, "" - }, ""), - &StringCharacters{ - AllowRanges: []unicode.RangeTable{ - {R16: []unicode.Range16{{'0', 'z', 1}}}, - }, - DisallowRanges: []unicode.RangeTable{ - {R16: []unicode.Range16{{0x003a, 0x0040, 1}}}, - {R16: []unicode.Range16{{0x005b, 0x005e, 1}}}, - {R16: []unicode.Range16{{0x0060, 0x0060, 1}}}, - }, - }, - }, - Message: msg, - } - require.Equal(t, msg, set.GetMessage(nil)) - - validator := buildFooValidator(JsonString, set, false) - obj := jsonObject(`{ - "foo": " this does not start with capital letter and has spaces (and punctuation) " - }`) - - ok, violations := validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, msg, violations[0].Message) - - // some more not oks... - obj["foo"] = "abcdefghijklmnopqrstuvwxyz" // not starts with capital - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, msg, violations[0].Message) - obj["foo"] = "AbcdefghijklmnopqrstuvwxyzAbcdefghijklmnopqrstuvwxyzAbcdefghijklmnopqrstuvwxyz" // too long - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, msg, violations[0].Message) - obj["foo"] = "Abc" // too short - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, msg, violations[0].Message) - obj["foo"] = "Abc." // contains invalid char - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, msg, violations[0].Message) - obj["foo"] = "" // empty string - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, msg, violations[0].Message) - obj["foo"] = " " // empty after trim - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, msg, violations[0].Message) -} - -func TestConstraintSetNoMsg(t *testing.T) { - set := &ConstraintSet{ - Constraints: Constraints{ - &StringNotEmpty{}, - &StringLength{Minimum: 16, Maximum: 64}, - NewCustomConstraint(func(value interface{}, vcx *ValidatorContext, this *CustomConstraint) (bool, string) { - if str, ok := value.(string); ok { - if str[0] < 'A' || str[0] > 'Z' { - return false, this.GetMessage(vcx) - } - } - return true, "" - }, "Must start with a capital"), - &StringCharacters{ - AllowRanges: []unicode.RangeTable{ - {R16: []unicode.Range16{{'0', 'z', 1}}}, - }, - DisallowRanges: []unicode.RangeTable{ - {R16: []unicode.Range16{{0x003a, 0x0040, 1}}}, - {R16: []unicode.Range16{{0x005b, 0x005e, 1}}}, - {R16: []unicode.Range16{{0x0060, 0x0060, 1}}}, - }, - }, - }, - Message: "", - } - // message should return first sub-constraint with non-empty message... - require.Equal(t, msgNotEmptyString, set.GetMessage(nil)) - - validator := buildFooValidator(JsonString, set, false) - obj := jsonObject(`{ - "foo": " this does not start with capital letter and has spaces (and punctuation) " - }`) - - ok, violations := validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, fmt.Sprintf(fmtMsgStringMinMaxLen, 16, tokenInclusive, 64, tokenInclusive), violations[0].Message) - - // some more not oks... - obj["foo"] = "abcdefghijklmnopqrstuvwxyz" // not starts with capital - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, "Must start with a capital", violations[0].Message) - obj["foo"] = "AbcdefghijklmnopqrstuvwxyzAbcdefghijklmnopqrstuvwxyzAbcdefghijklmnopqrstuvwxyz" // too long - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, fmt.Sprintf(fmtMsgStringMinMaxLen, 16, tokenInclusive, 64, tokenInclusive), violations[0].Message) - obj["foo"] = "Abc" // too short - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, fmt.Sprintf(fmtMsgStringMinMaxLen, 16, tokenInclusive, 64, tokenInclusive), violations[0].Message) - obj["foo"] = "Abc.01234567890123456" // contains invalid char - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, msgInvalidCharacters, violations[0].Message) - obj["foo"] = "" // empty string - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, msgNotEmptyString, violations[0].Message) -} - -func TestConstraintSetCeases(t *testing.T) { - set := &ConstraintSet{ - Constraints: Constraints{ - &StringNotEmpty{}, - &StringLength{Minimum: 16, Maximum: 64}, - NewCustomConstraint(func(value interface{}, vcx *ValidatorContext, this *CustomConstraint) (bool, string) { - if str, ok := value.(string); ok { - if str[0] < 'A' || str[0] > 'Z' { - vcx.CeaseFurther() - } - } - return true, "" - }, "Must start with a capital"), - &StringCharacters{ - AllowRanges: []unicode.RangeTable{ - {R16: []unicode.Range16{{'0', 'z', 1}}}, - }, - DisallowRanges: []unicode.RangeTable{ - {R16: []unicode.Range16{{0x003a, 0x0040, 1}}}, - {R16: []unicode.Range16{{0x005b, 0x005e, 1}}}, - {R16: []unicode.Range16{{0x0060, 0x0060, 1}}}, - }, - }, - }, - Message: "", - } - validator := buildFooValidator(JsonString, set, false) - obj := jsonObject(`{ - "foo": "this does not start with capital" - }`) - - // the custom constraint ceased further and passed - so validation passes... - ok, violations := validator.Validate(obj) - require.True(t, ok) - require.Equal(t, 0, len(violations)) - - // some more not oks... - obj["foo"] = "AbcdefghijklmnopqrstuvwxyzAbcdefghijklmnopqrstuvwxyzAbcdefghijklmnopqrstuvwxyz" // too long - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, fmt.Sprintf(fmtMsgStringMinMaxLen, 16, tokenInclusive, 64, tokenInclusive), violations[0].Message) - obj["foo"] = "Abc" // too short - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, fmt.Sprintf(fmtMsgStringMinMaxLen, 16, tokenInclusive, 64, tokenInclusive), violations[0].Message) - obj["foo"] = "Abc.01234567890123456" // contains invalid char - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, msgInvalidCharacters, violations[0].Message) - obj["foo"] = "" // empty string - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, msgNotEmptyString, violations[0].Message) -} - -func TestConstraintSetOneOf(t *testing.T) { - constraint1 := &testConstraint{passes: false, stops: false} - constraint2 := &testConstraint{passes: true, stops: false} - set := &ConstraintSet{ - OneOf: true, - Constraints: Constraints{constraint1, constraint2}, - } - require.Equal(t, fmt.Sprintf(fmtMsgConstraintSetDefaultOneOf, 2), set.GetMessage(nil)) - - validator := buildFooValidator(JsonString, set, false) - obj := jsonObject(`{ - "foo": "anything" - }`) - ok, _ := validator.Validate(obj) - require.True(t, ok) - - // the second passing doesn't get reached if first stops... - constraint1.stops = true - ok, violations := validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, fmt.Sprintf(fmtMsgConstraintSetDefaultOneOf, 2), violations[0].Message) - - constraint1.stops = false - constraint1.msg = "first message" - constraint2.msg = "second message" - constraint2.passes = false - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, "first message", violations[0].Message) -} - -func TestConstraintSetDefaultMessage(t *testing.T) { - set := &ConstraintSet{ - Constraints: Constraints{&testConstraint{}}, - } - require.Equal(t, fmt.Sprintf(fmtMsgConstraintSetDefaultAllOf, 1), set.GetMessage(nil)) - - validator := buildFooValidator(JsonString, set, false) - obj := jsonObject(`{ - "foo": "anything" - }`) - ok, violations := validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, fmt.Sprintf(fmtMsgConstraintSetDefaultAllOf, 1), violations[0].Message) - - set.OneOf = true - require.Equal(t, fmt.Sprintf(fmtMsgConstraintSetDefaultOneOf, 1), set.GetMessage(nil)) - ok, violations = validator.Validate(obj) - require.False(t, ok) - require.Equal(t, 1, len(violations)) - require.Equal(t, fmt.Sprintf(fmtMsgConstraintSetDefaultOneOf, 1), violations[0].Message) -} - -func TestConstraintSetWithConditionals(t *testing.T) { - cc1 := &ConditionalConstraint{ - When: []string{"AA"}, - Constraint: &StringNotEmpty{ - Message: "MSG_1", - }, - } - cc2 := &ConditionalConstraint{ - When: []string{"BB"}, - Constraint: &StringNotEmpty{ - Message: "MSG_2", - }, - } - set := &ConstraintSet{ - Constraints: Constraints{cc1, cc2}, - } - vcx := newValidatorContext(nil, nil, false, nil) - ok, _ := set.Check("", vcx) - require.True(t, ok) - - vcx.SetCondition("BB") - ok, msg := set.Check("", vcx) - require.False(t, ok) - require.Equal(t, "MSG_2", msg) - - vcx.SetCondition("AA") - ok, msg = set.Check("", vcx) - require.False(t, ok) - require.Equal(t, "MSG_1", msg) +func TestIsConditional(t *testing.T) { + c := &ConditionalConstraint{} + _, isCond := isConditional(c) + require.True(t, isCond) - vcx.ClearCondition("AA") - vcx.ClearCondition("BB") - set.OneOf = true - ok, msg = set.Check("", vcx) - require.False(t, ok) - require.Equal(t, "Constraint set must pass one of 2 undisclosed validations", msg) - vcx.SetCondition("AA") - ok, msg = set.Check("", vcx) - require.False(t, ok) - require.Equal(t, "MSG_1", msg) - vcx.ClearCondition("AA") - vcx.SetCondition("BB") - ok, msg = set.Check("", vcx) - require.False(t, ok) - require.Equal(t, "MSG_2", msg) - vcx.SetCondition("AA") - ok, msg = set.Check("", vcx) - require.False(t, ok) - require.Equal(t, "MSG_1", msg) + c2 := &StringNotEmpty{} + _, isCond = isConditional(c2) + require.False(t, isCond) } type testConstraint struct { diff --git a/constraint_utils.go b/constraint_utils.go index c183d9e..365582e 100644 --- a/constraint_utils.go +++ b/constraint_utils.go @@ -50,6 +50,7 @@ const ( msgPositiveOrZero = "Value must be positive or zero" msgNegative = "Value must be negative" msgNegativeOrZero = "Value must be negative or zero" + msgNull = "Value must be null" fmtMsgGt = "Value must be greater than %[1]v" fmtMsgGte = "Value must be greater than or equal to %[1]v" fmtMsgLt = "Value must be less than %[1]v" diff --git a/constraints_net.go b/constraints_net.go index 1ed5f07..7742c8c 100644 --- a/constraints_net.go +++ b/constraints_net.go @@ -383,7 +383,7 @@ func useNetwork(addr string, v4, v6 bool) string { return addr } -// NetIsURI constraint to check that string value is a valid URN +// NetIsURI constraint to check that string value is a valid URI type NetIsURI struct { // if set, the host is also checked (see also AllowIPAddress and others) CheckHost bool `v8n:"default"` diff --git a/constraints_special.go b/constraints_special.go index 2ae4bd2..2b6c406 100644 --- a/constraints_special.go +++ b/constraints_special.go @@ -419,22 +419,6 @@ const ( arrayconditionalConstraintName = "ArrayConditionalConstraint" ) -type Conditional interface { - MeetsConditions(vcx *ValidatorContext) bool -} - -func isConditional(c Constraint) (Conditional, bool) { - cc, ok := c.(Conditional) - return cc, ok -} - -func isCheckRequired(c Constraint, vcx *ValidatorContext) bool { - if cc, ok := isConditional(c); ok { - return cc.MeetsConditions(vcx) - } - return true -} - // ConditionalConstraint is a special constraint that wraps another constraint - but the wrapped // constraint is only checked when the specified when condition is met type ConditionalConstraint struct { @@ -444,17 +428,23 @@ type ConditionalConstraint struct { Others OthersExpr // Constraint is the wrapped constraint Constraint Constraint + // FailNotMet specifies that the conditional constraint should fail if the conditions are not met + // + // By default, if the conditions are not met the conditional constraint passes (without calling the wrapped constraint) + FailNotMet bool + // NotMetMessage is the message used when FailNotMet is set and the conditions are not met + NotMetMessage string } func (c *ConditionalConstraint) Check(v interface{}, vcx *ValidatorContext) (bool, string) { if c.MeetsConditions(vcx) { return c.Constraint.Check(v, vcx) } - return true, c.GetMessage(vcx) + return !c.FailNotMet, c.GetMessage(vcx) } func (c *ConditionalConstraint) GetMessage(tcx I18nContext) string { - return "" + return ternary(c.FailNotMet).string(c.NotMetMessage, "") } func (c *ConditionalConstraint) MeetsConditions(vcx *ValidatorContext) bool { @@ -544,3 +534,156 @@ func (c *ArrayConditionalConstraint) Check(v interface{}, vcx *ValidatorContext) func (c *ArrayConditionalConstraint) GetMessage(tcx I18nContext) string { return "" } + +// ConstraintSet is a constraint that contains other constraints +// +// The contained constraints are checked sequentially but the overall +// set stops on the first failing constraint +type ConstraintSet struct { + // Constraints is the slice of constraints within the set + Constraints Constraints `v8n:"default"` + // when set to true, OneOf specifies that the constraint set should pass just one of + // the contained constraints (rather than all of them) + OneOf bool + // Message is the violation message to be used if any of the constraints fail + // + // If the message is empty, the message from the first failing contained constraint is used + Message string + // Stop when set to true, prevents further validation checks on the property if this constraint set fails + Stop bool +} + +const ( + constraintSetName = "ConstraintSet" + constraintSetFieldConstraints = "Constraints" + constraintSetFieldOneOf = "OneOf" + constraintSetFieldMessage = constraintPtyNameMessage + constraintSetFieldStop = constraintPtyNameStop + fmtMsgConstraintSetDefaultAllOf = "Constraint set must pass all of %[1]d undisclosed validations" + fmtMsgConstraintSetDefaultOneOf = "Constraint set must pass one of %[1]d undisclosed validations" +) + +// Check implements the Constraint.Check and checks the constraints within the set +func (c *ConstraintSet) Check(v interface{}, vcx *ValidatorContext) (bool, string) { + if c.OneOf { + return c.checkOneOf(v, vcx) + } else { + return c.checkAllOf(v, vcx) + } +} + +func (c *ConstraintSet) checkAllOf(v interface{}, vcx *ValidatorContext) (bool, string) { + for _, cc := range c.Constraints { + if isCheckRequired(cc, vcx) { + if ok, msg := cc.Check(v, vcx); !ok { + if c.Message == "" && msg != "" { + vcx.CeaseFurtherIf(c.Stop) + return false, msg + } + vcx.CeaseFurtherIf(c.Stop) + return false, c.GetMessage(vcx) + } + if !vcx.continueAll || !vcx.continuePty() { + break + } + } + } + return true, "" +} + +func (c *ConstraintSet) checkOneOf(v interface{}, vcx *ValidatorContext) (bool, string) { + finalOk := false + firstMsg := "" + for _, cc := range c.Constraints { + if isCheckRequired(cc, vcx) { + if ok, msg := cc.Check(v, vcx); ok { + finalOk = true + break + } else if firstMsg == "" { + firstMsg = msg + } + if !vcx.continueAll || !vcx.continuePty() { + break + } + } + } + if finalOk { + return true, "" + } + vcx.CeaseFurtherIf(c.Stop) + if c.Message == "" && firstMsg != "" { + return false, firstMsg + } + return false, c.GetMessage(vcx) +} + +// GetMessage implements the Constraint.GetMessage +func (c *ConstraintSet) GetMessage(tcx I18nContext) string { + if c.Message == "" { + for _, sc := range c.Constraints { + if msg := sc.GetMessage(tcx); msg != "" { + return msg + } + } + // if we get here then the message is still empty!... + if c.OneOf { + return obtainI18nContext(tcx).TranslateFormat(fmtMsgConstraintSetDefaultOneOf, len(c.Constraints)) + } + return obtainI18nContext(tcx).TranslateFormat(fmtMsgConstraintSetDefaultAllOf, len(c.Constraints)) + } + return obtainI18nContext(tcx).TranslateMessage(c.Message) +} + +// IsNull is a utility constraint to check that a value is null +// +// Normally, null checking would be performed by the PropertyValidator.NotNull setting - however, +// it may be the case that, under certain conditions, null is the required value +type IsNull struct { + // the violation message to be used if the constraint fails (see Violation.Message) + // + // (if the Message is an empty string then the default violation message is used) + Message string `v8n:"default"` + // when set to true, Stop prevents further validation checks on the property if this constraint fails + Stop bool +} + +// Check implements the Constraint.Check and checks the constraints within the set +func (c *IsNull) Check(v interface{}, vcx *ValidatorContext) (bool, string) { + if v != nil { + vcx.CeaseFurtherIf(c.Stop) + return false, c.GetMessage(vcx) + } + return true, "" +} + +// GetMessage implements the Constraint.GetMessage +func (c *IsNull) GetMessage(tcx I18nContext) string { + return defaultMessage(tcx, c.Message, msgNull) +} + +// IsNotNull is a utility constraint to check that a value is not null +// +// Normally, null checking would be performed by the PropertyValidator.NotNull setting - however, +// it may be the case that null is only disallowed under certain conditions +type IsNotNull struct { + // the violation message to be used if the constraint fails (see Violation.Message) + // + // (if the Message is an empty string then the default violation message is used) + Message string `v8n:"default"` + // when set to true, Stop prevents further validation checks on the property if this constraint fails + Stop bool +} + +// Check implements the Constraint.Check and checks the constraints within the set +func (c *IsNotNull) Check(v interface{}, vcx *ValidatorContext) (bool, string) { + if v == nil { + vcx.CeaseFurtherIf(c.Stop) + return false, c.GetMessage(vcx) + } + return true, "" +} + +// GetMessage implements the Constraint.GetMessage +func (c *IsNotNull) GetMessage(tcx I18nContext) string { + return defaultMessage(tcx, c.Message, msgValueCannotBeNull) +} diff --git a/constraints_special_test.go b/constraints_special_test.go index f02c3eb..e6db1dc 100644 --- a/constraints_special_test.go +++ b/constraints_special_test.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "testing" + "unicode" "github.com/stretchr/testify/require" ) @@ -1029,6 +1030,43 @@ func TestConditionalConstraint_Others(t *testing.T) { require.Equal(t, "", violations[0].Path) } +func TestConditionalConstraint_FailNotMet(t *testing.T) { + v := &Validator{ + IgnoreUnknownProperties: true, + Properties: Properties{ + "foo": { + Type: JsonString, + Mandatory: true, + Constraints: Constraints{ + &ConditionalConstraint{ + Constraint: &StringNotBlank{}, + When: Conditions{"METHOD_POST"}, + FailNotMet: true, + NotMetMessage: "Conditions not met", + }, + }, + }, + }, + } + obj := jsonObject(`{ + "foo": "" + }`) + + ok, violations := v.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, "Conditions not met", violations[0].Message) + require.Equal(t, "foo", violations[0].Property) + require.Equal(t, "", violations[0].Path) + + ok, violations = v.Validate(obj, "METHOD_POST") + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msgNotBlankString, violations[0].Message) + require.Equal(t, "foo", violations[0].Property) + require.Equal(t, "", violations[0].Path) +} + func TestSetConditionIf(t *testing.T) { v := &Validator{ Properties: Properties{ @@ -1145,12 +1183,341 @@ func TestSetConditionIf_NoLeaks(t *testing.T) { require.Equal(t, "HERE", violations[1].Message) } -func TestIsConditional(t *testing.T) { - c := &ConditionalConstraint{} - _, isCond := isConditional(c) - require.True(t, isCond) +func TestConstraintSet(t *testing.T) { + const msg = "String value length must be between 16 and 64 chars; must be letters (upper or lower), digits or underscores; must start with an uppercase letter" + set := &ConstraintSet{ + Constraints: Constraints{ + &StringNotEmpty{}, + &StringLength{Minimum: 16, Maximum: 64}, + NewCustomConstraint(func(value interface{}, vcx *ValidatorContext, this *CustomConstraint) (bool, string) { + if str, ok := value.(string); ok { + if len(str) == 0 || str[0] < 'A' || str[0] > 'Z' { + return false, this.GetMessage(vcx) + } + } + return true, "" + }, ""), + &StringCharacters{ + AllowRanges: []unicode.RangeTable{ + {R16: []unicode.Range16{{'0', 'z', 1}}}, + }, + DisallowRanges: []unicode.RangeTable{ + {R16: []unicode.Range16{{0x003a, 0x0040, 1}}}, + {R16: []unicode.Range16{{0x005b, 0x005e, 1}}}, + {R16: []unicode.Range16{{0x0060, 0x0060, 1}}}, + }, + }, + }, + Message: msg, + } + require.Equal(t, msg, set.GetMessage(nil)) + + validator := buildFooValidator(JsonString, set, false) + obj := jsonObject(`{ + "foo": " this does not start with capital letter and has spaces (and punctuation) " + }`) - c2 := &StringNotEmpty{} - _, isCond = isConditional(c2) - require.False(t, isCond) + ok, violations := validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msg, violations[0].Message) + + // some more not oks... + obj["foo"] = "abcdefghijklmnopqrstuvwxyz" // not starts with capital + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msg, violations[0].Message) + obj["foo"] = "AbcdefghijklmnopqrstuvwxyzAbcdefghijklmnopqrstuvwxyzAbcdefghijklmnopqrstuvwxyz" // too long + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msg, violations[0].Message) + obj["foo"] = "Abc" // too short + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msg, violations[0].Message) + obj["foo"] = "Abc." // contains invalid char + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msg, violations[0].Message) + obj["foo"] = "" // empty string + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msg, violations[0].Message) + obj["foo"] = " " // empty after trim + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msg, violations[0].Message) +} + +func TestConstraintSetNoMsg(t *testing.T) { + set := &ConstraintSet{ + Constraints: Constraints{ + &StringNotEmpty{}, + &StringLength{Minimum: 16, Maximum: 64}, + NewCustomConstraint(func(value interface{}, vcx *ValidatorContext, this *CustomConstraint) (bool, string) { + if str, ok := value.(string); ok { + if str[0] < 'A' || str[0] > 'Z' { + return false, this.GetMessage(vcx) + } + } + return true, "" + }, "Must start with a capital"), + &StringCharacters{ + AllowRanges: []unicode.RangeTable{ + {R16: []unicode.Range16{{'0', 'z', 1}}}, + }, + DisallowRanges: []unicode.RangeTable{ + {R16: []unicode.Range16{{0x003a, 0x0040, 1}}}, + {R16: []unicode.Range16{{0x005b, 0x005e, 1}}}, + {R16: []unicode.Range16{{0x0060, 0x0060, 1}}}, + }, + }, + }, + Message: "", + } + // message should return first sub-constraint with non-empty message... + require.Equal(t, msgNotEmptyString, set.GetMessage(nil)) + + validator := buildFooValidator(JsonString, set, false) + obj := jsonObject(`{ + "foo": " this does not start with capital letter and has spaces (and punctuation) " + }`) + + ok, violations := validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, fmt.Sprintf(fmtMsgStringMinMaxLen, 16, tokenInclusive, 64, tokenInclusive), violations[0].Message) + + // some more not oks... + obj["foo"] = "abcdefghijklmnopqrstuvwxyz" // not starts with capital + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, "Must start with a capital", violations[0].Message) + obj["foo"] = "AbcdefghijklmnopqrstuvwxyzAbcdefghijklmnopqrstuvwxyzAbcdefghijklmnopqrstuvwxyz" // too long + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, fmt.Sprintf(fmtMsgStringMinMaxLen, 16, tokenInclusive, 64, tokenInclusive), violations[0].Message) + obj["foo"] = "Abc" // too short + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, fmt.Sprintf(fmtMsgStringMinMaxLen, 16, tokenInclusive, 64, tokenInclusive), violations[0].Message) + obj["foo"] = "Abc.01234567890123456" // contains invalid char + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msgInvalidCharacters, violations[0].Message) + obj["foo"] = "" // empty string + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msgNotEmptyString, violations[0].Message) +} + +func TestConstraintSetCeases(t *testing.T) { + set := &ConstraintSet{ + Constraints: Constraints{ + &StringNotEmpty{}, + &StringLength{Minimum: 16, Maximum: 64}, + NewCustomConstraint(func(value interface{}, vcx *ValidatorContext, this *CustomConstraint) (bool, string) { + if str, ok := value.(string); ok { + if str[0] < 'A' || str[0] > 'Z' { + vcx.CeaseFurther() + } + } + return true, "" + }, "Must start with a capital"), + &StringCharacters{ + AllowRanges: []unicode.RangeTable{ + {R16: []unicode.Range16{{'0', 'z', 1}}}, + }, + DisallowRanges: []unicode.RangeTable{ + {R16: []unicode.Range16{{0x003a, 0x0040, 1}}}, + {R16: []unicode.Range16{{0x005b, 0x005e, 1}}}, + {R16: []unicode.Range16{{0x0060, 0x0060, 1}}}, + }, + }, + }, + Message: "", + } + validator := buildFooValidator(JsonString, set, false) + obj := jsonObject(`{ + "foo": "this does not start with capital" + }`) + + // the custom constraint ceased further and passed - so validation passes... + ok, violations := validator.Validate(obj) + require.True(t, ok) + require.Equal(t, 0, len(violations)) + + // some more not oks... + obj["foo"] = "AbcdefghijklmnopqrstuvwxyzAbcdefghijklmnopqrstuvwxyzAbcdefghijklmnopqrstuvwxyz" // too long + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, fmt.Sprintf(fmtMsgStringMinMaxLen, 16, tokenInclusive, 64, tokenInclusive), violations[0].Message) + obj["foo"] = "Abc" // too short + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, fmt.Sprintf(fmtMsgStringMinMaxLen, 16, tokenInclusive, 64, tokenInclusive), violations[0].Message) + obj["foo"] = "Abc.01234567890123456" // contains invalid char + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msgInvalidCharacters, violations[0].Message) + obj["foo"] = "" // empty string + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msgNotEmptyString, violations[0].Message) +} + +func TestConstraintSetOneOf(t *testing.T) { + constraint1 := &testConstraint{passes: false, stops: false} + constraint2 := &testConstraint{passes: true, stops: false} + set := &ConstraintSet{ + OneOf: true, + Constraints: Constraints{constraint1, constraint2}, + } + require.Equal(t, fmt.Sprintf(fmtMsgConstraintSetDefaultOneOf, 2), set.GetMessage(nil)) + + validator := buildFooValidator(JsonString, set, false) + obj := jsonObject(`{ + "foo": "anything" + }`) + ok, _ := validator.Validate(obj) + require.True(t, ok) + + // the second passing doesn't get reached if first stops... + constraint1.stops = true + ok, violations := validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, fmt.Sprintf(fmtMsgConstraintSetDefaultOneOf, 2), violations[0].Message) + + constraint1.stops = false + constraint1.msg = "first message" + constraint2.msg = "second message" + constraint2.passes = false + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, "first message", violations[0].Message) +} + +func TestConstraintSetDefaultMessage(t *testing.T) { + set := &ConstraintSet{ + Constraints: Constraints{&testConstraint{}}, + } + require.Equal(t, fmt.Sprintf(fmtMsgConstraintSetDefaultAllOf, 1), set.GetMessage(nil)) + + validator := buildFooValidator(JsonString, set, false) + obj := jsonObject(`{ + "foo": "anything" + }`) + ok, violations := validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, fmt.Sprintf(fmtMsgConstraintSetDefaultAllOf, 1), violations[0].Message) + + set.OneOf = true + require.Equal(t, fmt.Sprintf(fmtMsgConstraintSetDefaultOneOf, 1), set.GetMessage(nil)) + ok, violations = validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, fmt.Sprintf(fmtMsgConstraintSetDefaultOneOf, 1), violations[0].Message) +} + +func TestConstraintSetWithConditionals(t *testing.T) { + cc1 := &ConditionalConstraint{ + When: []string{"AA"}, + Constraint: &StringNotEmpty{ + Message: "MSG_1", + }, + } + cc2 := &ConditionalConstraint{ + When: []string{"BB"}, + Constraint: &StringNotEmpty{ + Message: "MSG_2", + }, + } + set := &ConstraintSet{ + Constraints: Constraints{cc1, cc2}, + } + vcx := newValidatorContext(nil, nil, false, nil) + ok, _ := set.Check("", vcx) + require.True(t, ok) + + vcx.SetCondition("BB") + ok, msg := set.Check("", vcx) + require.False(t, ok) + require.Equal(t, "MSG_2", msg) + + vcx.SetCondition("AA") + ok, msg = set.Check("", vcx) + require.False(t, ok) + require.Equal(t, "MSG_1", msg) + + vcx.ClearCondition("AA") + vcx.ClearCondition("BB") + set.OneOf = true + ok, msg = set.Check("", vcx) + require.False(t, ok) + require.Equal(t, "Constraint set must pass one of 2 undisclosed validations", msg) + vcx.SetCondition("AA") + ok, msg = set.Check("", vcx) + require.False(t, ok) + require.Equal(t, "MSG_1", msg) + vcx.ClearCondition("AA") + vcx.SetCondition("BB") + ok, msg = set.Check("", vcx) + require.False(t, ok) + require.Equal(t, "MSG_2", msg) + vcx.SetCondition("AA") + ok, msg = set.Check("", vcx) + require.False(t, ok) + require.Equal(t, "MSG_1", msg) +} + +func TestIsNull(t *testing.T) { + validator := buildFooValidator(JsonString, &IsNull{}, false) + obj := jsonObject(`{ + "foo": null + }`) + ok, _ := validator.Validate(obj) + require.True(t, ok) + + obj["foo"] = "not null" + ok, violations := validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msgNull, violations[0].Message) + require.Equal(t, "foo", violations[0].Property) + require.Equal(t, "", violations[0].Path) +} + +func TestIsNotNull(t *testing.T) { + validator := buildFooValidator(JsonString, &IsNotNull{}, false) + obj := jsonObject(`{ + "foo": "not null" + }`) + ok, _ := validator.Validate(obj) + require.True(t, ok) + + obj["foo"] = nil + ok, violations := validator.Validate(obj) + require.False(t, ok) + require.Equal(t, 1, len(violations)) + require.Equal(t, msgValueCannotBeNull, violations[0].Message) + require.Equal(t, "foo", violations[0].Property) + require.Equal(t, "", violations[0].Path) } diff --git a/i18n.go b/i18n.go index 9cae792..268d8c7 100644 --- a/i18n.go +++ b/i18n.go @@ -176,6 +176,7 @@ var internalMessages = map[string]string{ msgPropertyRequiredWhen: msgPropertyRequiredWhen, msgPropertyUnwantedWhen: msgPropertyUnwantedWhen, msgValueCannotBeNull: msgValueCannotBeNull, + msgNull: msgNull, msgValueMustBeObject: msgValueMustBeObject, msgValueMustBeArray: msgValueMustBeArray, msgValueMustBeObjectOrArray: msgValueMustBeObjectOrArray, diff --git a/i18n_translations.go b/i18n_translations.go index 8740f18..eb05efb 100644 --- a/i18n_translations.go +++ b/i18n_translations.go @@ -786,6 +786,13 @@ var defaultInternalTranslator = &internalTranslator{ langIt: "Il valore non può essere nullo", langDe: "Wert darf nicht null sein", }, + msgNull: { + langEn: msgNull, + langFr: "La valeur doit être nulle", + langEs: "El valor debe ser nulo", + langIt: "Il valore deve essere nullo", + langDe: "Wert muss null sein", + }, msgValueMustBeArray: { langEn: msgValueMustBeArray, langFr: "La valeur doit être un tableau",