NAME

VERSION

DESCRIPTION

TYPE: undef

This type does not have any clauses. The only value it knows is the undefined value (like undef in Perl, or null in PHP).

ROLE: BaseType

This is the base type role, all Sah types (except undef) must implement this role.

Clauses

The list below is ordered by priority, from highest to lowest.

defhash_v : FLOAT

Priority: 0 (checked first before everything else).

Category: metadata.

From DefHash. Normally there is no need to set this.

v : FLOAT (default: 1)

Priority: 0 (checked first before everything else).

Category: metadata.

From DefHash. Specify Sah version. Should be 1 at the moment.

schema_v : FLOAT (default: 1)

Priority: 0 (checked first before everything else).

Category: metadata.

Specify schema version. By default assumed to be 1 if not set.

base_v : FLOAT (default: 1)

Priority: 0 (checked first before everything else).

Category: metadata.

Specify base schema version. By default assumed to be 1 if not set. Using a base schema with a different value will fail. Can be used to force child schemas to update whenever we change our schema. For example:

then consonant will silently break because of clash (overriding) in the match clause. To force consonant to fail (so its author can update it, should the authors of vocal and consonant are two different persons):

// the new vocal
["str", {"schema_v": 2, "match": "\\A[aeiou]\\z"}]

Since vocal's schema_v is now 2, it is not the same as 1 (which is implied by consonant, having the default value of base_v). consonant's author might then update its own implementation to match vocal:

summary : STR

Priority: 2 (very high), after default.

Category: metadata.

From DefHash. A one-line text (about 72 characters maximum, without any formatting) to describe the schema. This is useful, e.g. for manually describing a schema instead of using the human compiler. It can also be used in form field labels.

To store translations, you can use the alt.lang.* clause attributes (or its shortcut form using (LANG) suffix).

req : BOOL

If set to 1, require that data be defined. Otherwise, allow data to be undef (the default behaviour).

By default, undef will pass even elaborate schema, e.g. ["int", {"min": 0, "max": 10, "div_by": 3}] will still pass an undef. However, undef will not pass ["int": {"req": 1}].

This behaviour is much like NULLs in SQL: we *can't* (in)validate something that is unknown/unset.

See also: forbidden

forbidden : BOOL

Priority: 3 (very high), executed after default.

Category: constraint.

This is the opposite of req, requiring that data be not defined (i.e. undef).

Given schema ["int", {"forbidden": 1}], a non-undef value will fail. Another example: the schema ["int", {"req": 1, "forbidden": 1}] will always fail due to conflicting clauses.

See also: req

prefilters : [EXPR, ...]

Priority: 10 (high). Run after default and req/forbidden.

Category: filter.

Attributes specific to this clause: temp (bool, default 0, if set to true then prefiltered value will only be used during validation and at the end of the clause set data will not use this value).

Run expression(s), usually to preprocess data before further checking. Data is referred to in expression by variable $_. Prefiltered value should persist until the end of all other clauses (until the end of clause set), after which the old value can be restored.

ok : ANY -> true

Priority: 50 (normal)

Return value: true (always succeeds).

Category: constraint.

Will do nothing. This clause is just a convenience if you want to do nothing (or perhaps just use the attributes of this clause to do things). It is the default in the else section of the if_clause clause.

clset : HASH -> INT

Evaluate a clause set. Note that return value adds 1 to the number of successful clauses to avoid returning 0 (evaluates to false). And it will only be returned if clause is successful. Otherwise false (0) will be returned. Example:

check_prop : [PROP, EXPR] -> ANY

Just like check, but instead of checking data itself, check property PROP. Example:

// require that the *length of* string is a prime number
["str", "check_prop", ["len", "is_prime($_)"]]
// check that the email's Subject header is a palindrome
["email", "check_prop", [["headers", "subject"], "is_palindrome($_)"]]

See also: prop

if : ([COND, THEN] -> ANY) or ([COND, THEN, ELSE] -> ANY)

Priority: 50 (normal)

Return value: if condition is true, then the THEN result, otherwise the ELSE result.

Category: constraint.

A generic condition clause. COND, THEN, and ELSE are either boolean values, expressions (if they are string) or a clause set (if they are hash) or a schema (if they are array). COND is evaluated, if the result is true then THEN is evaluated, otherwise ELSE is evaluated. ELSE is optional.

Examples:

// forbid the string to be lowercase
"if": [{"match": "^[a-z]$"}, false]
// if string is lowercase, it must be a palindrome
"if": [{"match": "^[a-z]$"}, "is_palindrome($_)"]
// if string is lowercase, it must be a palindrome, otherwise it must be longer
// than 3 characters.
"if": [{"match": "^[a-z]$"}, "is_palindrome($_)", "len($_) > 3"]
// require the length of the string to be an even number
"if": [{"prop": ["len", ["int", "div_by", 2]]}, true}
// if string is a palindrome, then require it to have length > 5
"if": [{"check": "is_palindrome($_)"}, ["len", ["int", "xmin": 5]]]

Note that you have to write schema in array form instead of string form, to avoid ambiguity with expression:

div_by : INT

TYPE: str

str stores strings (text). This type assumes the Comparable, Sortable, and HasElems roles (the elements are individual characters, the indices are integers from 0 to (length of string)-1). Default encoding is utf8.

Clauses

match : REGEX|{COMPILER=>REGEX, ...}

Require that string match the specified regular expression.

Since regular expressions might not be 100% compatible from language to language, instead of avoiding the use of regex entirely, you can specify different regex for each target language, e.g.:

then {} will still become {} after validation. In both cases, {"b": null} will still become {"b": 2}.

re_keys : HASH

Attributes: restrict (bool, default: 1)

Just like keys, but specifies schemas for keys which match regexes. Example:

["hash", "re_keys", {"^[A-Za-z]": "str", "^[0-9]": "int"}]

The above schema specifies that for keys which begin with a letter the values must be strings, and for keys which begin with a digit the values must be integers. These hashes validate: {}, {"a": "x", "b": 1, "1": 1}. These hashes do not validate: {"1": "x"}, {"#": "x"} (key does not match any keys in re_keys).

req_keys : ARRAY

Specify which keys are required to be present. Note that the values for those keys are not required to be defined (use keys for that). Example:

["hash", "req_keys", ["a", "b"]]

The above schema specifies that hash needs to have some keys, but the value can be null. This hash will validate: {"a": 1, "b": null}. However, given this schema:

["hash", "req_keys", ["a", "b"], "keys", {"a": "int", "b": "int*"}]

the previous hash will not validate since the value for b is required.

allowed_keys : ARRAY

Specify which keys are allowed.

allowed_keys_re : RE

Like allowed_keys but using regular expression.

each_key : SCHEMA

Alias to each_index.

each_value : SCHEMA

Alias to each_elem.

check_each_key : EXPR

Alias to check_each_index.

check_each_value : EXPR

Alias to check_each_elem.

TYPE: any

A type to specify alternate schemas.

Clauses

of : [SCHEMA, ...]

Specify the schema(s) where the value will need to be valid to at least one of them.

TYPE: all

A type to specify co-schemas (all schemas that must be validated to value).

Clauses

of : [SCHEMA, ...]

Specify the schema(s) where the value will need to be valid to all of them.