# Builtin Validation Rules

    library(fluffy)

fluffy has 31 validation rules and 10 cross rules.

### Validation rules

    Registry()@rule_names
    #>  [1] "required"       "default"        "coerce"         "apply"
    #>  [5] "type"           "inherits"       "allowed"        "forbidden"
    #>  [9] "unique"         "positive"       "negative"       "finite"
    #> [13] "allow_na"       "sorted"         "min_val"        "max_val"
    #> [17] "min_length"     "max_length"     "min_nrow"       "max_nrow"
    #> [21] "min_nchar"      "max_nchar"      "nzchar"         "regex"
    #> [25] "levels"         "ordered_levels" "dependency"     "dependencies"
    #> [29] "predicate"      "coerce_last"    "apply_last"

The builtin rules are categorised by their type: ‘control’, ‘transform’, ‘validate’ and ‘finalize’. When the `Validator` is run, rules are applied in four passes according to these categories, with the ‘finalize’ pass being unique in that rules in this group only operate if all rules in the schema node passed validation without error.

Rules within each category are applied in the order they appear in their respective `Registry` property.

    r <- Registry()
    r@control_rules
    #> [1] "required" "default"
    r@transform_rules
    #> [1] "coerce" "apply"
    r@validate_rules
    #>  [1] "type"           "inherits"       "allowed"        "forbidden"
    #>  [5] "unique"         "positive"       "negative"       "finite"
    #>  [9] "allow_na"       "sorted"         "min_val"        "max_val"
    #> [13] "min_length"     "max_length"     "min_nrow"       "max_nrow"
    #> [17] "min_nchar"      "max_nchar"      "nzchar"         "regex"
    #> [21] "levels"         "ordered_levels" "dependency"     "dependencies"
    #> [25] "predicate"
    r@finalize_rules
    #> [1] "coerce_last" "apply_last"

Each validation rule has two functions associated with it:

- A function that validates the given schema value.

    Schema(list(type = 1L), error = TRUE)
    #> Error:
    #> ! <fluffy::Schema> object is invalid:
    #> - Schema validation failed with the following errors:
    #> └─ type: Must be a function or a string.

- A function that uses the schema value to validate data.

    Validator(
      data = 1L,
      schema = list(type = "character"),
      error = TRUE
    )
    #> Error:
    #> ! <fluffy::Validator> object is invalid:
    #> - Data validation failed with the following errors:
    #> └─ type: Is not type `character`.

### Cross rules

Cross rules operate within the `Schema`, checking that the values of two or more schema rules don’t clash. They are not exhaustive, but apply to a number of common scenarios.

    Schema(
      list(
        min_length = 5,
        max_length = 1
      ),
      error = TRUE
    )
    #> Error:
    #> ! <fluffy::Schema> object is invalid:
    #> - Schema validation failed with the following errors:
    #> ├─ min_length: `min_length` must be smaller than `max_length`.
    #> └─ max_length: `min_length` must be smaller than `max_length`.

### Rule information

fluffy rules that test for behaviour typically employ `na.rm = TRUE` for validation. For example, the `nchar` rule check is implemented like so:

    any(nchar(field) > schema_field, na.rm = TRUE)

If you wish to handle `NA` values differently, you must write custom rules.

#### Validation rules

Rule | Schema operation | Data operation | Control flow
--- | --- | --- | ---
| Checks schema value is: | Checks/transforms data element: | Stops other rules if:
`required` | boolean. | exists. | FALSE and element not present.
`default` | non-empty. | exists and inserts `default` if not. | default is used.
`apply` | function or a valid string. | applies function. |
`coerce` | 1 arg function or a valid string. | coerces. |
`type` | 1 arg function or a valid string. | type. |
`inherits` | character vector. | inherits from specified classes. |
`allowed` | non-empty vector. | only values in `allowed` set. |
`forbidden` | non-empty vector. | no values in `forbidden` set. |
`unique` | TRUE. | no duplicates. |
`positive` | TRUE. | is positive (or zero). |
`negative` | TRUE. | is negative (or zero). |
`finite` | TRUE. | is finite. |
`allow_na` | FALSE. | no `NA` values. |
`sorted` | TRUE. | is sorted. |
`min_val` | finite numeric value. | values at least `min_val`. |
`max_val` | finite numeric value. | values at most `max_val`. |
`min_length` | positive integerish value. | length at least `min_length`. |
`max_length` | positive integerish value. | length at most `max_length`. |
`min_nrow` | positive integerish value. | nrow at least `min_nrow`. |
`max_nrow` | positive integerish value. | nrow at most `max_nrow`. |
`min_nchar` | positive integerish value. | nchar at least `min_nchar`. |
`max_nchar` | positive integerish value. | nchar at most `max_nchar`. |
`nzchar` | boolean. | no empty strings. |
`regex` | string. | matches `regex` pattern. |
`levels` | character vector. | has levels matching `levels` in any order. |
`ordered_levels` | character vector. | has levels matching `ordered_levels` in order. |
`dependency` | character vector, or integerish vector, or list of string/integerish scalars. | dependency field present. |
`dependencies` | list of character vectors, or integerish vectors, or lists of string/integerish scalars. | dependency fields present. |
`predicate` | function or a valid string. | satisfies predicate function. |
`apply_last` | function or a valid string. | applies function if no errors in node. |
`coerce_last` | 1 arg function or a valid string. | coerces if no errors in node. |

#### Cross rules

Cross rule | Schema operation
--- | ---
| Checks in a schema node that:
`dependency_and_dependencies` | `dependency` and `dependencies` rules aren’t both present.
`required_and_default` | if `required` is TRUE that a `default` value is not provided.
`positive_and_negative` | `positive` and `negative` rules aren’t both present.
`min_val_larger_than_max_val` | `min_val` is smaller than `max_val`.
`min_length_larger_than_max_length` | `min_length` is smaller than `max_length`.
`min_nrow_larger_than_max_nrow` | `min_nrow` is smaller than `max_nrow`.
`min_nchar_larger_than_max_nchar` | `min_nchar` is smaller than `max_nchar`.
`allowed_and_forbidden_overlap` | values in `allowed` and `forbidden` do not overlap.
`allowed_type_mismatch` | values in `allowed` are of the type specified in `type`.
`forbidden_type_mismatch` | values in `forbidden` are of the type specified in `type`.

##### Note

To quickly see the builtin rules at the terminal, use `show_builtins()`.