Skip to content
This repository has been archived by the owner on Nov 3, 2023. It is now read-only.

Commit

Permalink
Fix if/then/else examples
Browse files Browse the repository at this point in the history
  • Loading branch information
jdesrosiers committed Mar 19, 2021
1 parent 861bd67 commit bd882e2
Showing 1 changed file with 63 additions and 12 deletions.
75 changes: 63 additions & 12 deletions source/reference/conditionals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,24 @@ constructs you've probably seen in traditional programming languages.
If ``if`` is valid, ``then`` must also be valid (and ``else`` is ignored.) If
``if`` is invalid, ``else`` must also be valid (and ``then`` is ignored).

If ``then`` or ``else`` is not defined, ``if`` behaves as if they have a value
of ``true``.

If ``then`` and/or ``else`` appear in a schema without ``if``, ``then`` and
``else`` are ignored.

We can put this in the form of a truth table, showing the combinations of when
``if``, ``then``, and ``else`` are valid and the resulting validity of the
entire schema:

==== ==== ==== ============
if then else whole schema
==== ==== ==== ============
X X
X
X X X
X
X X
X X X
X X X X
T T n/a T
T F n/a F
F n/a T T
F n/a F F
n/a n/a T
==== ==== ==== ============

For example, let's say you wanted to write a schema to handle addresses in the
Expand All @@ -54,6 +58,7 @@ letters and numbers alternate.
"type": "string"
},
"country": {
"default": "United States of America",
"enum": ["United States of America", "Canada"]
}
},
Expand All @@ -63,7 +68,7 @@ letters and numbers alternate.
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
},
"else": {
"else": {
"properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
}
}
Expand All @@ -72,7 +77,12 @@ letters and numbers alternate.
"street_address": "1600 Pennsylvania Avenue NW",
"country": "United States of America",
"postal_code": "20500"
}
}
--
{
"street_address": "1600 Pennsylvania Avenue NW",
"postal_code": "20500"
}
--
{
"street_address": "24 Sussex Drive",
Expand All @@ -85,6 +95,20 @@ letters and numbers alternate.
"country": "Canada",
"postal_code": "10000"
}
--X
{
"street_address": "1600 Pennsylvania Avenue NW",
"postal_code": "K1M 1M4"
}

.. note::

In this example, "country" is not a required property. Because the "if"
schema also doesn't require the "country" property, it will pass and the
"then" schema will apply. Therefore, if the "country" property is not
defined, the default behavior is to validate "postal_code" as a USA postal
code. The "default" keyword doesn't have an effect, but is nice to include
for readers of the schema to more easily recognize the default behavior.

Unfortunately, this approach above doesn't scale to more than two countries. You
can, however, wrap pairs of ``if`` and ``then`` inside an ``allOf`` to create
Expand All @@ -102,6 +126,7 @@ to the remaining postal codes of the world.
"type": "string"
},
"country": {
"default": "United States of America",
"enum": ["United States of America", "Canada", "Netherlands"]
}
},
Expand All @@ -116,15 +141,17 @@ to the remaining postal codes of the world.
},
{
"if": {
"properties": { "country": { "const": "Canada" } }
"properties": { "country": { "const": "Canada" } },
"required": ["country"]
},
"then": {
"properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
}
},
{
"if": {
"properties": { "country": { "const": "Netherlands" } }
"properties": { "country": { "const": "Netherlands" } },
"required": ["country"]
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" } }
Expand All @@ -137,7 +164,12 @@ to the remaining postal codes of the world.
"street_address": "1600 Pennsylvania Avenue NW",
"country": "United States of America",
"postal_code": "20500"
}
}
--
{
"street_address": "1600 Pennsylvania Avenue NW",
"postal_code": "20500"
}
--
{
"street_address": "24 Sussex Drive",
Expand All @@ -156,5 +188,24 @@ to the remaining postal codes of the world.
"country": "Canada",
"postal_code": "10000"
}
--X
{
"street_address": "1600 Pennsylvania Avenue NW",
"postal_code": "K1M 1M4"
}

.. note::

The "required" keyword is necessary in the "if" schemas or they would all
apply if the "country" is not defined. Leaving "required" off of the
"United States of America" "if" schema makes it effectively the default if
no "country" is defined.

.. note::

Even if "country" was a required field, it's still recommended to have the
"required" keyword in each "if" schema. The validation result will be the
same because "required" will fail, but not including it will add noise to
error results because it will validate the "postal_code" against all three
of the "then" schemas leading to irrelevant errors.

0 comments on commit bd882e2

Please sign in to comment.