Skip to content

Validators

Checked, not run

comline build verifies validators — an unknown validator name, a keyword argument that isn't a property or whose literal type is wrong, or an undeclared params.* reference all fail the build. Running them against data (in generated code) is not done yet — see the design note.

A validator is a named, parameterised check you attach to a struct or error field.

/// Checks a string's length is within bounds.
/// @min_chars: minimum length
/// @max_chars: maximum length
validator StringBounds {
    min_chars: u32 = 0
    max_chars: u32 = 1024

    validate {
        assert(value.length >= params.min_chars,
               "{value.name} must be at least {params.min_chars} characters")
        assert(value.length <= params.max_chars,
               "{value.name} must be at most {params.max_chars} characters")
    }
}

Properties

name: Type [= default], one per line — the same shape as a struct field, minus optional and annotations. They are the validator's configuration, supplied where the validator is used.

validate

A validate block holds one or more assert(condition, message) calls.

  • condition — member paths over value.* (the field under check) and params.* (this validator's properties), compared with == != >= <= > < and joined by and / or. assert(c, m) passes when c is true.
  • message — an interpolated string; {value.…} and {params.…} placeholders are substituted.

The condition language is deliberately small and non-computational — no precedence, no loops, no bindings.

Using one — @validators

Attach validators to a field with the @validators annotation: a list of calls that bind the validator's properties by name.

1
2
3
4
struct Message {
    @validators = [StringBounds(min_chars = 3, max_chars = 12)]
    recipient: str
}

Unbound properties fall back to their declared default. Errors' fields take @validators too.