Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

validate.schema

import validate.schema

validate lifts part of this module out to its own top level; each name below is shown with the path that reaches it. Anything still spelled validate.schema.* needs import validate.schema.

validate.schema

Provides the Schema class which binds a ruleset dictionary to data and produces a structured validation result.

Features

  • Dot-notation keys: "address.city" resolves nested dictionaries.
  • Wildcard keys: "tags.*" validates every item in a list against a Validator chain.
  • Bail-on-first-error per field (default) or collect-all-errors mode.
  • Sometimes: skip rules when a field is absent.
  • Nullable: treat nil as passing for all subsequent rules.
  • Label override: substitute a human-readable name in error messages.
  • Required-field checking: fields with required() that are entirely absent from the data dict are caught and reported.
  • check(data): returns { valid: bool, errors: list }.
  • check_or_raise(data): raises ValidationError on failure.

Classes

ValidationError

class validate.ValidationError < Error

Raised by Schema.check_or_raise() when validation fails.

The errors property holds the same list of { field, message } dicts that Schema.check() returns under the errors key.

catch {
  schema.check_or_raise(req.body)
} as e

if e {
  echo e.message   # "Validation failed"
  echo e.errors    # [{ field: 'email', message: '...' }, ...]
}

Fields

FieldTypeDescription
errorsList of { field: string, message: string } dictionaries, one per failed rule.

Constructor

validate.ValidationError(errors)

Parameters

  • errors (list) — Validation error list from Schema.check().

Schema

class validate.Schema

Binds a ruleset to data and validates it.

Basic usage
import validate

var schema = validate.schema({
  name:  validate.required().string().max_length(100),
  email: validate.required().string().email(),
  age:   validate.required().integer().gte(18),
})

var result = schema.check({
  name:  'Ada Lovelace',
  email: 'ada@example.com',
  age:   36,
})

echo result.valid   # true
echo result.errors  # []
Nested field validation (dot-notation)
var schema = validate.schema({
  'address.city':    validate.required().string(),
  'address.country': validate.required().string().length(2).uppercase(),
})

schema.check({
  address: { city: 'Lagos', country: 'NG' }
})
Wildcard list validation
var schema = validate.schema({
  'tags.*': validate.required().string().max_length(32),
})

schema.check({ tags: ['zuri', 'backend', 'fast'] })
Raising on failure
catch {
  schema.check_or_raise(data)
} as e

if e {
  # e.errors is a list of { field, message } dicts
  for err in e.errors {
    echo '${err.field}: ${err.message}'
  }
}
schema.check_or_raise(data)
Grouped errors (errors keyed by field)
var result = schema.check(data)
var grouped = schema.group_errors(result.errors)
# { email: ['must be valid email'], age: ['must be >= 18'] }

Constructor

validate.Schema(ruleset)

Parameters

  • ruleset (dict) — Map of field keys to Validator instances.

Raises ArgumentError When ruleset is not a dictionary.

Raises ValueError When a key is not a string or a value is not a Validator.

Schema.check()

validate.Schema.check(data) -> dict

Validates data against the schema and returns a result dictionary.

The result always has the shape:

{
  valid:  bool,
  errors: list<{ field: string, message: string }>
}

Fields present in the data but absent from the schema are silently ignored. Fields present in the schema but absent from the data are validated against their rules (the required rule catches absent fields; all other rules skip nil values unless chained after required).

Parameters

  • data (dict)

Returns dict

Raises ArgumentError

Schema.check_or_raise()

validate.Schema.check_or_raise(data) -> dict

Validates data and raises a ValidationError if validation fails. Returns the result dictionary on success.

def create_user(req, res) {
  catch {
    schema.check_or_raise(req.body)
  } as e

  if e {
    return res.json({ errors: e.errors }, 422)
  }

  return res.json({ ok: true })
}

Parameters

  • data (dict)

Returns dict

Raises ValidationError

Raises ArgumentError

Schema.group_errors()

validate.Schema.group_errors(errors) -> dict

Converts a flat errors list (as returned by check) into a dictionary keyed by field name, where each value is a list of error message strings.

var result  = schema.check(data)
var grouped = schema.group_errors(result.errors)
# { 'email': ['must be a valid email address'], 'age': ['must be >= 18'] }

Parameters

  • errors (list) — The errors list from a check() result.

Returns dict

Schema.first_error()

validate.Schema.first_error(errors, field_key) -> string|nil

Returns the first error message for the given field, or nil when that field has no errors in the provided errors list.

var result = schema.check(data)
var msg    = schema.first_error(result.errors, 'email')

Parameters

  • errors (list) — The errors list from a check() result.
  • field_key (string) — The field to look up.

Returns string|nil

Schema.field_errors()

validate.Schema.field_errors(errors, field_key) -> list<string>

Returns all error messages for the given field as a list, or an empty list when that field has no errors.

Parameters

  • errors (list)
  • field_key (string)

Returns list<string>

Schema.has_error()

validate.Schema.has_error(errors, field_key) -> bool

Returns true when the given field has at least one error in the provided errors list.

Parameters

  • errors (list)
  • field_key (string)

Returns bool

Schema.ruleset()

validate.Schema.ruleset() -> dict

Returns a copy of this schema’s own ruleset dictionary (field key → Validator). A copy, not a live reference, so mutating the result can never affect this Schema itself.

Returns dict

Schema.extend()

validate.Schema.extend(other) -> Schema

Extends this schema with additional rules from another schema or a plain ruleset dictionary, returning a new Schema instance. Rules in other override rules for the same field key.

var base   = validate.schema({ name: validate.required().string() })
var extended = base.extend({
  email: validate.required().string().email(),
})

Parameters

  • other (dict|Schema)

Returns Schema

Schema.only()

validate.Schema.only(keys) -> Schema

Returns a new Schema containing only the rules for the given field keys.

var partial = full_schema.only(['name', 'email'])

Parameters

  • keys (list)

Returns Schema

Schema.except()

validate.Schema.except(keys) -> Schema

Returns a new Schema with the rules for the given field keys removed.

var without_admin = schema.except(['role', 'is_superuser'])

Parameters

  • keys (list)

Returns Schema