Kwalify Users' Guide (for Ruby and Java)

2   Tips

2-1   Enclose Key Names in (Double) Quotes

It is allowed to enclose key name in quotes (') or double-quotes (") in YAML. This tip highlights user-defined key names.

schema11a.yaml : enclosing in double-quotes
type:   map
mapping:
  "name":
    required:  yes
  "email":
    pattern:   /@/
  "age":
    type:      int
  "birth":
    type:      date

You may prefer to indent with 1 space and 3 spaces.

schema11b.yaml : indent with 1 space and 3 spaces
type:   map
mapping:
 "name":
    required:  yes
 "email":
    pattern:   /@/
 "age":
    type:      int
 "birth":
    type:      date

2-2   JSON

JSON is a lightweight data-interchange format, especially useful for JavaScript. JSON can be considered as a subset of YAML. It means that YAML parser can parse JSON and Kwalify can validate JSON document.

schema12.yaml : an example schema written in JSON format
{ "type": "map",
  "required": true,
  "mapping": {
    "name":   { "type": "str", "required": true },
    "email":  { "type": "str" },
    "age":    { "type": "int" },
    "gender": { "type": "str", "enum": ["M", "F"] },
    "favorite": { "type": "seq",
                  "sequence": [
                     { "type": "str" }
                   ]
                 }
  }
}
document12a.yaml : valid JSON document example
{ "name": "Foo",
  "email": "foo@mail.com",
  "age": 20,
  "gender": "F",
  "favorite": [
     "football",
     "basketball",
     "baseball"
  ]
}
validate
$ kwalify -lf schema12.yaml document12a.yaml
document12a.yaml#0: valid.
document12b.yaml : invalid JSON document example
{
  "mail": "foo@mail.com",
  "age": twenty,
  "gender": "X",
  "favorite": [ 123, 456 ]
}
validate
$ kwalify -lf schema12.yaml document12b.yaml
document12b.yaml#0: INVALID
  - (line 1) [/] key 'name:' is required.
  - (line 2) [/mail] key 'mail:' is undefined.
  - (line 3) [/age] 'twenty': not a integer.
  - (line 4) [/gender] 'X': invalid gender value.
  - (line 5) [/favorite/0] '123': not a string.
  - (line 5) [/favorite/1] '456': not a string.

2-3   Anchor

You can share schemas with YAML anchor.

schema13.yaml : anchor example
type:   seq
sequence:
  - &employee
    type:      map
    mapping:
     "given-name": &name
        type:     str
        required: yes
     "family-name": *name
     "post":
        enum:
          - exective
          - manager
          - clerk
     "supervisor":  *employee

Anchor is also available in YAML document.

document13a.yaml : valid document example
- &foo
  given-name:    foo
  family-name:   Foo
  post:          exective
- &bar
  given-name:    bar
  family-name:   Bar
  post:          manager
  supervisor:    *foo
- given-name:    baz
  family-name:   Baz
  post:          clerk
  supervisor:    *bar
- given-name:    zak
  family-name:   Zak
  post:          clerk
  supervisor:    *bar
validate
$ kwalify -lf schema13.yaml document13a.yaml
document13a.yaml#0: valid.

2-4   Default of Mapping

YAML allows user to specify default value of mapping.

For example, the following YAML document uses default value of mapping.

A: 10
B: 20
=: -1      # default value

This is equal to the following Ruby code.

map = ["A"=>10, "B"=>20]
map.default = -1
map

Kwalify allows user to specify default rule using default value of mapping. It is useful when key names are unknown.

schema14.yaml : default rule example
type: map
mapping:
  =:              # default rule
    type: number
    range: { max: 1, min: -1 }
document14a.yaml : valid document example
value1: 0
value2: 0.5
value3: -0.9
validate
$ kwalify -lf schema14.yaml document14a.yaml
document14a.yaml#0: valid.
document14b.yaml : invalid document example
value1: 0
value2: 1.1
value3: -2.0
validate
$ kwalify -lf schema14.yaml document14b.yaml
document14b.yaml#0: INVALID
  - (line 2) [/value2] '1.1': too large (> max 1).
  - (line 3) [/value3] '-2.0': too small (< min -1).

2-5   Merging Mappings

YAML allows user to merge mappings.

- &a1
  A: 10
  B: 20
- <<: *a1            # merge
  A: 15              # override
  C: 30              # add

This is equal to the following Ruby code.

a1 = {"A"=>10, "B"=>20}
tmp = {}
tmp.update(a1)       # merge
tmp["A"] = 15        # override
tmp["C"] = 30        # add

This feature allows Kwalify to merge rule entries.

schema15.yaml : merging rule entries example
type: map
mapping:
 "group":
    type: map
    mapping:
     "name": &name
        type: str
        required: yes
     "email": &email
        type: str
        pattern: /@/
        required: no
 "user":
    type: map
    mapping:
     "name":
        <<: *name             # merge
        length: { max: 16 }   # override
     "email":
        <<: *email            # merge
        required: yes         # add
document15a.yaml : valid document example
group:
  name: foo
  email: foo@mail.com
user:
  name: bar
  email: bar@mail.com
validate
$ kwalify -lf schema15.yaml document15a.yaml
document15a.yaml#0: valid.
document15b.yaml : invalid document example
group:
  name: foo
  email: foo@mail.com
user:
  name: toooooo-looooong-name
validate
$ kwalify -lf schema15.yaml document15b.yaml
document15b.yaml#0: INVALID
  - (line 4) [/user] key 'email:' is required.
  - (line 5) [/user/name] 'toooooo-looooong-name': too long (length 21 > max 16).