From: Philippe Proulx Date: Thu, 28 May 2020 18:18:48 +0000 (-0400) Subject: barectf: schemas: use conditionals intead of `oneOf` when possible X-Git-Tag: v3.0.0~188 X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=f1ac89a942375a2ea1faba880598dc3fdbe289d2;p=barectf.git barectf: schemas: use conditionals intead of `oneOf` when possible 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 --- diff --git a/barectf/schemas/2/config/config-pre-field-type-expansion.yaml b/barectf/schemas/2/config/config-pre-field-type-expansion.yaml index 756139a..1431355 100644 --- a/barectf/schemas/2/config/config-pre-field-type-expansion.yaml +++ b/barectf/schemas/2/config/config-pre-field-type-expansion.yaml @@ -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: diff --git a/barectf/schemas/2/config/config.yaml b/barectf/schemas/2/config/config.yaml index 0f07e44..80a77c5 100644 --- a/barectf/schemas/2/config/config.yaml +++ b/barectf/schemas/2/config/config.yaml @@ -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 diff --git a/barectf/schemas/2/config/field-type.yaml b/barectf/schemas/2/config/field-type.yaml index 26d5c5a..c41aaf2 100644 --- a/barectf/schemas/2/config/field-type.yaml +++ b/barectf/schemas/2/config/field-type.yaml @@ -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 diff --git a/barectf/schemas/2/config/include-prop.yaml b/barectf/schemas/2/config/include-prop.yaml index b2b8869..23cc1df 100644 --- a/barectf/schemas/2/config/include-prop.yaml +++ b/barectf/schemas/2/config/include-prop.yaml @@ -24,9 +24,11 @@ $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