barectf: schemas: use conditionals intead of `oneOf` when possible
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 28 May 2020 18:18:48 +0000 (14:18 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 29 May 2020 19:23:10 +0000 (15:23 -0400)
Using `if`/`then`/`else` instead of `oneOf` makes the `jsonschema`
validator create much more readable errors.

For example:

Before:
    Error:
      Configuration: Cannot create configuration from YAML file
        `config.yaml`
      Configuration object:
      `metadata` property:
      `clocks` property:
      `some_clock` property:
      `offset` property:
      `seconds` property: -2 is not valid under any of the given
        schemas: -2 is less than the minimum of 0; -2 is not of type
        'null' (from schema `2/config/config`)

Now:
    Error:
      Configuration: Cannot create configuration from YAML file
        `config.yaml`
      Configuration object:
      `metadata` property:
      `clocks` property:
      `some_clock` property:
      `offset` property:
      `seconds` property: -2 is less than the minimum of 0
        (from schema `2/config/config`)

This is because, with conditionals, we assume that the user intended
something with some valid schema, and add more constraints. The example
above is for an integer having a minimum value of 0, or a null value. As
soon as we know that the value is an integer, then we know its minimum
must be 0; we decide to not care about the fact that the whole value
could also be null (which the old message indicated). In my opinion,
this is a better UX.

The example above is simple. For more complex schemas, the UX gain is
even more obvious.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
barectf/schemas/2/config/config-pre-field-type-expansion.yaml
barectf/schemas/2/config/config.yaml
barectf/schemas/2/config/field-type.yaml
barectf/schemas/2/config/include-prop.yaml

index 756139a7d2d12288ffa9291940294a28f66a9656..143135578ff91c63562c0619b86e1f0c7d28b890 100644 (file)
@@ -27,37 +27,39 @@ title: Configuration object before field type expansions
 definitions:
   partial-field-type:
     title: Partial field type object
-    oneOf:
-      - type: string
-      - type: object
-        allOf:
-          - oneOf:
-            - properties:
-                class:
-                  type: string
-              required:
-                - class
-            - properties:
-                inherit:
-                  type: string
-              required:
-                - inherit
-            - properties:
-                $inherit:
-                  type: string
-              required:
-                - $inherit
-          - properties:
-              value-type:
-                $ref: '#/definitions/partial-field-type'
-              element-type:
-                $ref: '#/definitions/partial-field-type'
-              fields:
-                type: object
-                patternProperties:
-                  '':
-                    $ref: '#/definitions/partial-field-type'
-      - type: 'null'
+    if:
+      type: object
+    then:
+      oneOf:
+        - properties:
+            class:
+              type: string
+          required:
+            - class
+        - properties:
+            inherit:
+              type: string
+          required:
+            - inherit
+        - properties:
+            $inherit:
+              type: string
+          required:
+            - $inherit
+      properties:
+        value-type:
+          $ref: '#/definitions/partial-field-type'
+        element-type:
+          $ref: '#/definitions/partial-field-type'
+        fields:
+          type: object
+          patternProperties:
+            '':
+              $ref: '#/definitions/partial-field-type'
+    else:
+      oneOf:
+        - type: string
+        - type: 'null'
 type: object
 properties:
   metadata:
index 0f07e44030b9ab26caef3c3fe364808a8cd1d168..80a77c5d820227fc66ea1d7a53d738c440623862 100644 (file)
@@ -34,18 +34,26 @@ definitions:
       - type: string
       - type: 'null'
   opt-int-min-0:
-    oneOf:
-      - type: integer
-        minimum: 0
-      - type: 'null'
+    if:
+      type: integer
+    then:
+      minimum: 0
+    else:
+      type: 'null'
   opt-field-type:
-    oneOf:
-      - $ref: https://barectf.org/schemas/2/config/field-type.json
-      - type: 'null'
+    if:
+      type: object
+    then:
+      $ref: https://barectf.org/schemas/2/config/field-type.json
+    else:
+      type: 'null'
   opt-struct-field-type:
-    oneOf:
-      - $ref: https://barectf.org/schemas/2/config/field-type.json#/definitions/struct-field-type
-      - type: 'null'
+    if:
+      type: object
+    then:
+      $ref: https://barectf.org/schemas/2/config/field-type.json#/definitions/struct-field-type
+    else:
+      type: 'null'
   trace:
     title: Trace object
     type: object
@@ -53,11 +61,15 @@ definitions:
       byte-order:
         $ref: https://barectf.org/schemas/2/config/byte-order-prop.json
       uuid:
-        oneOf:
-          - $ref: https://barectf.org/schemas/2/config/uuid-prop.json
-          - type: string
-            const: auto
-          - type: 'null'
+        if:
+          type: string
+        then:
+          oneOf:
+            - $ref: https://barectf.org/schemas/2/config/uuid-prop.json
+            - type: string
+              const: auto
+        else:
+          type: 'null'
       packet-header-type:
         $ref: '#/definitions/opt-struct-field-type'
     required:
@@ -80,28 +92,35 @@ definitions:
                 - return-ctype
     properties:
       uuid:
-        oneOf:
-          - $ref: https://barectf.org/schemas/2/config/uuid-prop.json
-          - type: 'null'
+        if:
+          type: object
+        then:
+          $ref: https://barectf.org/schemas/2/config/uuid-prop.json
+        else:
+          type: 'null'
       description:
         $ref: '#/definitions/opt-string'
       freq:
-        oneOf:
-          - type: integer
-            minimum: 1
-          - type: 'null'
+        if:
+          type: integer
+        then:
+          minimum: 1
+        else:
+          type: 'null'
       error-cycles:
         $ref: '#/definitions/opt-int-min-0'
       offset:
-        oneOf:
-          - type: object
-            properties:
-              cycles:
-                $ref: '#/definitions/opt-int-min-0'
-              seconds:
-                $ref: '#/definitions/opt-int-min-0'
-            additionalProperties: false
-          - type: 'null'
+        if:
+          type: object
+        then:
+          properties:
+            cycles:
+              $ref: '#/definitions/opt-int-min-0'
+            seconds:
+              $ref: '#/definitions/opt-int-min-0'
+          additionalProperties: false
+        else:
+          type: 'null'
       absolute:
         $ref: '#/definitions/opt-bool'
       return-ctype:
@@ -110,10 +129,12 @@ definitions:
         $ref: '#/definitions/opt-string'
     additionalProperties: false
   $default-stream:
-    oneOf:
-      - type: string
-        pattern: '^[A-Za-z_][A-Za-z0-9_]*$'
-      - type: 'null'
+    if:
+      type: string
+    then:
+      pattern: '^[A-Za-z_][A-Za-z0-9_]*$'
+    else:
+      type: 'null'
   stream:
     title: Stream object
     type: object
@@ -194,15 +215,17 @@ properties:
         $ref: '#/definitions/trace'
       env:
         title: Environment variables
-        oneOf:
-          - type: object
-            patternProperties:
-              '^[A-Za-z_][A-Za-z0-9_]*$':
-                oneOf:
-                  - type: string
-                  - type: integer
-            additionalProperties: false
-          - type: 'null'
+        if:
+          type: object
+        then:
+          patternProperties:
+            '^[A-Za-z_][A-Za-z0-9_]*$':
+              oneOf:
+                - type: string
+                - type: integer
+          additionalProperties: false
+        else:
+          type: 'null'
       clocks:
         title: Clocks object
         type: object
index 26d5c5ae6619e2019e5d06690943d9ecba8a75f5..c41aaf29de81535327a9765b8313ffb6ac65053e 100644 (file)
@@ -27,20 +27,26 @@ title: Effective field type object
 definitions:
   byte-order-prop:
     title: Byte order property value
-    oneOf:
-      - $ref: https://barectf.org/schemas/2/config/byte-order-prop.json
-      - type: 'null'
+    if:
+      type: object
+    then:
+      $ref: https://barectf.org/schemas/2/config/byte-order-prop.json
+    else:
+      type: 'null'
   align-prop:
     title: Alignment property value
-    oneOf:
-      - type: integer
-        minimum: 1
-      - type: 'null'
+    if:
+      type: integer
+    then:
+      minimum: 1
+    else:
+      type: 'null'
   encoding-prop:
     title: Encoding property value
-    oneOf:
-      - type: string
-        enum:
+    if:
+      type: string
+    then:
+      enum:
         - utf8
         - UTF8
         - utf-8
@@ -52,7 +58,8 @@ definitions:
         - none
         - None
         - NONE
-      - type: 'null'
+    else:
+      type: 'null'
   int-field-type-class-prop:
     type: string
     enum:
@@ -77,39 +84,43 @@ definitions:
       byte-order:
         $ref: '#/definitions/byte-order-prop'
       base:
-        type: string
-        oneOf:
-          - enum:
+        if:
+          type: string
+        then:
+          enum:
             - bin
             - oct
             - dec
             - hex
-          - type: 'null'
+        else:
+          type: 'null'
       encoding:
         $ref: '#/definitions/encoding-prop'
       property-mappings:
-        oneOf:
-          - type: array
-            items:
-              type: object
-              properties:
-                type:
-                  type: string
-                  const: clock
-                name:
-                  type: string
-                  pattern: '^[A-Za-z_][A-Za-z0-9_]*$'
-                property:
-                  type: string
-                  const: value
-              required:
-                - type
-                - name
-                - property
-              additionalProperties: false
-            minItems: 1
-            maxItems: 1
-          - type: 'null'
+        if:
+          type: array
+        then:
+          items:
+            type: object
+            properties:
+              type:
+                type: string
+                const: clock
+              name:
+                type: string
+                pattern: '^[A-Za-z_][A-Za-z0-9_]*$'
+              property:
+                type: string
+                const: value
+            required:
+              - type
+              - name
+              - property
+            additionalProperties: false
+          minItems: 1
+          maxItems: 1
+        else:
+          type: 'null'
     required:
       - class
       - size
@@ -172,24 +183,28 @@ definitions:
       members:
         type: array
         items:
-          anyOf:
-            - type: string
-            - type: object
-              properties:
-                label:
-                  type: string
-                value:
-                  oneOf:
-                    - type: integer
-                    - type: array
-                      items:
-                        type: integer
-                      minItems: 2
-                      maxItems: 2
-              required:
-                - label
-                - value
-              additionalProperties: false
+          if:
+            type: object
+          then:
+            properties:
+              label:
+                type: string
+              value:
+                if:
+                  type: array
+                then:
+                  items:
+                    type: integer
+                  minItems: 2
+                  maxItems: 2
+                else:
+                  type: integer
+            additionalProperties: false
+            required:
+              - label
+              - value
+          else:
+            type: string
     required:
       - class
       - value-type
@@ -243,13 +258,15 @@ definitions:
       min-align:
         $ref: '#/definitions/align-prop'
       fields:
-        oneOf:
-          - type: object
-            patternProperties:
-              '^[A-Za-z_][A-Za-z0-9_]*$':
-                $ref: '#/definitions/field-type'
-            additionalProperties: false
-          - type: 'null'
+        if:
+          type: object
+        then:
+          patternProperties:
+            '^[A-Za-z_][A-Za-z0-9_]*$':
+              $ref: '#/definitions/field-type'
+          additionalProperties: false
+        else:
+          type: 'null'
     required:
       - class
     additionalProperties: false
index b2b8869e4cbed7ccd406f285a64aab09cbd81cf9..23cc1df10802ecab39d64eb51876801e1ece1313 100644 (file)
 $schema: http://json-schema.org/draft-07/schema#
 $id: https://barectf.org/schemas/2/config/include-prop.json
 title: Inclusion property value
-oneOf:
-  - type: string
-  - type: array
-    items:
-      type: string
-    minItems: 1
+if:
+  type: array
+then:
+  items:
+    type: string
+  minItems: 1
+else:
+  type: string
This page took 0.028159 seconds and 4 git commands to generate.