diff --git a/schema.json b/schema.json index e35c026a..30a5ae8e 100644 --- a/schema.json +++ b/schema.json @@ -14,36 +14,9 @@ "content": { "application/json": { "schema": { - "anyOf": [ - { - "$ref": "#/components/schemas/Product-Input" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Input" - }, - { - "$ref": "#/components/schemas/Mask-Input" - }, - { - "$ref": "#/components/schemas/Snake-Input" - }, - { - "$ref": "#/components/schemas/Concat-Input" - }, - { - "$ref": "#/components/schemas/Squash-Input" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Input" } ], "title": "Spec", @@ -238,36 +211,9 @@ "content": { "application/json": { "schema": { - "anyOf": [ - { - "$ref": "#/components/schemas/Product-Input" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Input" - }, - { - "$ref": "#/components/schemas/Mask-Input" - }, - { - "$ref": "#/components/schemas/Snake-Input" - }, - { - "$ref": "#/components/schemas/Concat-Input" - }, - { - "$ref": "#/components/schemas/Squash-Input" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Input" } ], "title": "Spec", @@ -328,36 +274,9 @@ "content": { "application/json": { "schema": { - "anyOf": [ - { - "$ref": "#/components/schemas/Product-Input" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Input" - }, - { - "$ref": "#/components/schemas/Mask-Input" - }, - { - "$ref": "#/components/schemas/Snake-Input" - }, - { - "$ref": "#/components/schemas/Concat-Input" - }, - { - "$ref": "#/components/schemas/Squash-Input" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Input" } ], "title": "Spec", @@ -531,106 +450,20 @@ "CombinationOf-Input": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Input" - }, - { - "$ref": "#/components/schemas/UnionOf-Input" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Input" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Input" } ], - "title": "Left", - "description": "The left-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Input", - "DifferenceOf": "#/components/schemas/DifferenceOf-Input", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Input", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Input", - "UnionOf": "#/components/schemas/UnionOf-Input" - } - } + "description": "The left-hand Region to combine" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Input" - }, - { - "$ref": "#/components/schemas/UnionOf-Input" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Input" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Input" } ], - "title": "Right", - "description": "The right-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Input", - "DifferenceOf": "#/components/schemas/DifferenceOf-Input", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Input", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Input", - "UnionOf": "#/components/schemas/UnionOf-Input" - } - } + "description": "The right-hand Region to combine" }, "type": { "type": "string", @@ -654,106 +487,20 @@ "CombinationOf-Output": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Output" - }, - { - "$ref": "#/components/schemas/UnionOf-Output" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Output" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Output" } ], - "title": "Left", - "description": "The left-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Output", - "DifferenceOf": "#/components/schemas/DifferenceOf-Output", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Output", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Output", - "UnionOf": "#/components/schemas/UnionOf-Output" - } - } + "description": "The left-hand Region to combine" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Output" - }, - { - "$ref": "#/components/schemas/UnionOf-Output" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Output" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Output" } ], - "title": "Right", - "description": "The right-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Output", - "DifferenceOf": "#/components/schemas/DifferenceOf-Output", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Output", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Output", - "UnionOf": "#/components/schemas/UnionOf-Output" - } - } + "description": "The right-hand Region to combine" }, "type": { "type": "string", @@ -777,106 +524,20 @@ "Concat-Input": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Input" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Input" - }, - { - "$ref": "#/components/schemas/Mask-Input" - }, - { - "$ref": "#/components/schemas/Snake-Input" - }, - { - "$ref": "#/components/schemas/Concat-Input" - }, - { - "$ref": "#/components/schemas/Squash-Input" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Input" } ], - "title": "Left", - "description": "The left-hand Spec to Concat, midpoints will appear earlier", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Input", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Input", - "Product": "#/components/schemas/Product-Input", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Input", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Input", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Input" - } - } + "description": "The left-hand Spec to Concat, midpoints will appear earlier" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Input" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Input" - }, - { - "$ref": "#/components/schemas/Mask-Input" - }, - { - "$ref": "#/components/schemas/Snake-Input" - }, - { - "$ref": "#/components/schemas/Concat-Input" - }, - { - "$ref": "#/components/schemas/Squash-Input" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Input" } ], - "title": "Right", - "description": "The right-hand Spec to Concat, midpoints will appear later", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Input", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Input", - "Product": "#/components/schemas/Product-Input", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Input", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Input", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Input" - } - } + "description": "The right-hand Spec to Concat, midpoints will appear later" }, "gap": { "type": "boolean", @@ -912,106 +573,20 @@ "Concat-Output": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Output" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Output" - }, - { - "$ref": "#/components/schemas/Mask-Output" - }, - { - "$ref": "#/components/schemas/Snake-Output" - }, - { - "$ref": "#/components/schemas/Concat-Output" - }, - { - "$ref": "#/components/schemas/Squash-Output" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Output" } ], - "title": "Left", - "description": "The left-hand Spec to Concat, midpoints will appear earlier", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Output", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Output", - "Product": "#/components/schemas/Product-Output", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Output", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Output", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Output" - } - } + "description": "The left-hand Spec to Concat, midpoints will appear earlier" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Output" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Output" - }, - { - "$ref": "#/components/schemas/Mask-Output" - }, - { - "$ref": "#/components/schemas/Snake-Output" - }, - { - "$ref": "#/components/schemas/Concat-Output" - }, - { - "$ref": "#/components/schemas/Squash-Output" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Output" } ], - "title": "Right", - "description": "The right-hand Spec to Concat, midpoints will appear later", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Output", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Output", - "Product": "#/components/schemas/Product-Output", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Output", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Output", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Output" - } - } + "description": "The right-hand Spec to Concat, midpoints will appear later" }, "gap": { "type": "boolean", @@ -1047,106 +622,20 @@ "DifferenceOf-Input": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Input" - }, - { - "$ref": "#/components/schemas/UnionOf-Input" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Input" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Input" } ], - "title": "Left", - "description": "The left-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Input", - "DifferenceOf": "#/components/schemas/DifferenceOf-Input", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Input", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Input", - "UnionOf": "#/components/schemas/UnionOf-Input" - } - } + "description": "The left-hand Region to combine" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Input" - }, - { - "$ref": "#/components/schemas/UnionOf-Input" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Input" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Input" - }, + "allOf": [ { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, - { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Input" } ], - "title": "Right", - "description": "The right-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Input", - "DifferenceOf": "#/components/schemas/DifferenceOf-Input", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Input", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Input", - "UnionOf": "#/components/schemas/UnionOf-Input" - } - } + "description": "The right-hand Region to combine" }, "type": { "type": "string", @@ -1170,106 +659,20 @@ "DifferenceOf-Output": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Output" - }, - { - "$ref": "#/components/schemas/UnionOf-Output" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Output" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Output" } ], - "title": "Left", - "description": "The left-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Output", - "DifferenceOf": "#/components/schemas/DifferenceOf-Output", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Output", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Output", - "UnionOf": "#/components/schemas/UnionOf-Output" - } - } + "description": "The left-hand Region to combine" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Output" - }, - { - "$ref": "#/components/schemas/UnionOf-Output" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Output" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Output" } ], - "title": "Right", - "description": "The right-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Output", - "DifferenceOf": "#/components/schemas/DifferenceOf-Output", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Output", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Output", - "UnionOf": "#/components/schemas/UnionOf-Output" - } - } + "description": "The right-hand Region to combine" }, "type": { "type": "string", @@ -1385,106 +788,20 @@ "IntersectionOf-Input": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Input" - }, - { - "$ref": "#/components/schemas/UnionOf-Input" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Input" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Input" } ], - "title": "Left", - "description": "The left-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Input", - "DifferenceOf": "#/components/schemas/DifferenceOf-Input", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Input", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Input", - "UnionOf": "#/components/schemas/UnionOf-Input" - } - } + "description": "The left-hand Region to combine" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Input" - }, - { - "$ref": "#/components/schemas/UnionOf-Input" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Input" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Input" } ], - "title": "Right", - "description": "The right-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Input", - "DifferenceOf": "#/components/schemas/DifferenceOf-Input", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Input", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Input", - "UnionOf": "#/components/schemas/UnionOf-Input" - } - } + "description": "The right-hand Region to combine" }, "type": { "type": "string", @@ -1508,106 +825,20 @@ "IntersectionOf-Output": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Output" - }, - { - "$ref": "#/components/schemas/UnionOf-Output" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Output" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Output" } ], - "title": "Left", - "description": "The left-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Output", - "DifferenceOf": "#/components/schemas/DifferenceOf-Output", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Output", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Output", - "UnionOf": "#/components/schemas/UnionOf-Output" - } - } + "description": "The left-hand Region to combine" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Output" - }, - { - "$ref": "#/components/schemas/UnionOf-Output" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Output" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Output" } ], - "title": "Right", - "description": "The right-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Output", - "DifferenceOf": "#/components/schemas/DifferenceOf-Output", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Output", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Output", - "UnionOf": "#/components/schemas/UnionOf-Output" - } - } + "description": "The right-hand Region to combine" }, "type": { "type": "string", @@ -1674,106 +905,20 @@ "Mask-Input": { "properties": { "spec": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Input" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Input" - }, - { - "$ref": "#/components/schemas/Mask-Input" - }, - { - "$ref": "#/components/schemas/Snake-Input" - }, - { - "$ref": "#/components/schemas/Concat-Input" - }, - { - "$ref": "#/components/schemas/Squash-Input" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Input" } ], - "title": "Spec", - "description": "The Spec containing the source midpoints", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Input", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Input", - "Product": "#/components/schemas/Product-Input", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Input", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Input", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Input" - } - } + "description": "The Spec containing the source midpoints" }, "region": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Input" - }, - { - "$ref": "#/components/schemas/UnionOf-Input" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Input" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Input" } ], - "title": "Region", - "description": "The Region that midpoints will be inside", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Input", - "DifferenceOf": "#/components/schemas/DifferenceOf-Input", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Input", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Input", - "UnionOf": "#/components/schemas/UnionOf-Input" - } - } + "description": "The Region that midpoints will be inside" }, "check_path_changes": { "type": "boolean", @@ -1803,106 +948,20 @@ "Mask-Output": { "properties": { "spec": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Output" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Output" - }, - { - "$ref": "#/components/schemas/Mask-Output" - }, - { - "$ref": "#/components/schemas/Snake-Output" - }, - { - "$ref": "#/components/schemas/Concat-Output" - }, - { - "$ref": "#/components/schemas/Squash-Output" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Output" } ], - "title": "Spec", - "description": "The Spec containing the source midpoints", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Output", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Output", - "Product": "#/components/schemas/Product-Output", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Output", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Output", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Output" - } - } + "description": "The Spec containing the source midpoints" }, "region": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Output" - }, - { - "$ref": "#/components/schemas/UnionOf-Output" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Output" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Output" } ], - "title": "Region", - "description": "The Region that midpoints will be inside", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Output", - "DifferenceOf": "#/components/schemas/DifferenceOf-Output", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Output", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Output", - "UnionOf": "#/components/schemas/UnionOf-Output" - } - } + "description": "The Region that midpoints will be inside" }, "check_path_changes": { "type": "boolean", @@ -1991,55 +1050,12 @@ "PointsRequest": { "properties": { "spec": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Input" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Input" - }, - { - "$ref": "#/components/schemas/Mask-Input" - }, - { - "$ref": "#/components/schemas/Snake-Input" - }, - { - "$ref": "#/components/schemas/Concat-Input" - }, - { - "$ref": "#/components/schemas/Squash-Input" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Input" } ], - "title": "Spec", - "description": "The spec from which to generate points", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Input", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Input", - "Product": "#/components/schemas/Product-Input", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Input", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Input", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Input" - } - } + "description": "The spec from which to generate points" }, "max_frames": { "anyOf": [ @@ -2123,106 +1139,20 @@ "Product-Input": { "properties": { "outer": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Input" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Input" - }, + "allOf": [ { - "$ref": "#/components/schemas/Mask-Input" - }, + "$ref": "#/components/schemas/Spec-Input" + } + ], + "description": "Will be executed once" + }, + "inner": { + "allOf": [ { - "$ref": "#/components/schemas/Snake-Input" - }, - { - "$ref": "#/components/schemas/Concat-Input" - }, - { - "$ref": "#/components/schemas/Squash-Input" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, - { - "$ref": "#/components/schemas/Spiral" - } - ], - "title": "Outer", - "description": "Will be executed once", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Input", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Input", - "Product": "#/components/schemas/Product-Input", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Input", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Input", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Input" - } - } - }, - "inner": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Input" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Input" - }, - { - "$ref": "#/components/schemas/Mask-Input" - }, - { - "$ref": "#/components/schemas/Snake-Input" - }, - { - "$ref": "#/components/schemas/Concat-Input" - }, - { - "$ref": "#/components/schemas/Squash-Input" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, - { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Input" } ], - "title": "Inner", - "description": "Will be executed len(outer) times", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Input", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Input", - "Product": "#/components/schemas/Product-Input", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Input", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Input", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Input" - } - } + "description": "Will be executed len(outer) times" }, "type": { "type": "string", @@ -2246,106 +1176,20 @@ "Product-Output": { "properties": { "outer": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Output" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Output" - }, - { - "$ref": "#/components/schemas/Mask-Output" - }, - { - "$ref": "#/components/schemas/Snake-Output" - }, - { - "$ref": "#/components/schemas/Concat-Output" - }, - { - "$ref": "#/components/schemas/Squash-Output" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Output" } ], - "title": "Outer", - "description": "Will be executed once", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Output", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Output", - "Product": "#/components/schemas/Product-Output", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Output", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Output", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Output" - } - } + "description": "Will be executed once" }, "inner": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Output" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Output" - }, - { - "$ref": "#/components/schemas/Mask-Output" - }, - { - "$ref": "#/components/schemas/Snake-Output" - }, - { - "$ref": "#/components/schemas/Concat-Output" - }, - { - "$ref": "#/components/schemas/Squash-Output" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Output" } ], - "title": "Inner", - "description": "Will be executed len(outer) times", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Output", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Output", - "Product": "#/components/schemas/Product-Output", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Output", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Output", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Output" - } - } + "description": "Will be executed len(outer) times" }, "type": { "type": "string", @@ -2461,6 +1305,104 @@ "title": "Rectangle", "description": "Mask contains points of axis within a rotated xy rectangle.\n\n.. example_spec::\n\n from scanspec.regions import Rectangle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Rectangle(\"x\", \"y\", 0, 1.1, 1.5, 2.1, 30)" }, + "Region-Input": { + "oneOf": [ + { + "$ref": "#/components/schemas/CombinationOf-Input" + }, + { + "$ref": "#/components/schemas/UnionOf-Input" + }, + { + "$ref": "#/components/schemas/IntersectionOf-Input" + }, + { + "$ref": "#/components/schemas/DifferenceOf-Input" + }, + { + "$ref": "#/components/schemas/SymmetricDifferenceOf-Input" + }, + { + "$ref": "#/components/schemas/Range" + }, + { + "$ref": "#/components/schemas/Rectangle" + }, + { + "$ref": "#/components/schemas/Polygon" + }, + { + "$ref": "#/components/schemas/Circle" + }, + { + "$ref": "#/components/schemas/Ellipse" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "Circle": "#/components/schemas/Circle", + "CombinationOf": "#/components/schemas/CombinationOf-Input", + "DifferenceOf": "#/components/schemas/DifferenceOf-Input", + "Ellipse": "#/components/schemas/Ellipse", + "IntersectionOf": "#/components/schemas/IntersectionOf-Input", + "Polygon": "#/components/schemas/Polygon", + "Range": "#/components/schemas/Range", + "Rectangle": "#/components/schemas/Rectangle", + "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Input", + "UnionOf": "#/components/schemas/UnionOf-Input" + } + } + }, + "Region-Output": { + "oneOf": [ + { + "$ref": "#/components/schemas/CombinationOf-Output" + }, + { + "$ref": "#/components/schemas/UnionOf-Output" + }, + { + "$ref": "#/components/schemas/IntersectionOf-Output" + }, + { + "$ref": "#/components/schemas/DifferenceOf-Output" + }, + { + "$ref": "#/components/schemas/SymmetricDifferenceOf-Output" + }, + { + "$ref": "#/components/schemas/Range" + }, + { + "$ref": "#/components/schemas/Rectangle" + }, + { + "$ref": "#/components/schemas/Polygon" + }, + { + "$ref": "#/components/schemas/Circle" + }, + { + "$ref": "#/components/schemas/Ellipse" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "Circle": "#/components/schemas/Circle", + "CombinationOf": "#/components/schemas/CombinationOf-Output", + "DifferenceOf": "#/components/schemas/DifferenceOf-Output", + "Ellipse": "#/components/schemas/Ellipse", + "IntersectionOf": "#/components/schemas/IntersectionOf-Output", + "Polygon": "#/components/schemas/Polygon", + "Range": "#/components/schemas/Range", + "Rectangle": "#/components/schemas/Rectangle", + "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Output", + "UnionOf": "#/components/schemas/UnionOf-Output" + } + } + }, "Repeat": { "properties": { "num": { @@ -2520,55 +1462,12 @@ "Snake-Input": { "properties": { "spec": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Input" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Input" - }, - { - "$ref": "#/components/schemas/Mask-Input" - }, - { - "$ref": "#/components/schemas/Snake-Input" - }, - { - "$ref": "#/components/schemas/Concat-Input" - }, - { - "$ref": "#/components/schemas/Squash-Input" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Input" } ], - "title": "Spec", - "description": "The Spec to run in reverse every other iteration", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Input", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Input", - "Product": "#/components/schemas/Product-Input", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Input", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Input", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Input" - } - } + "description": "The Spec to run in reverse every other iteration" }, "type": { "type": "string", @@ -2591,55 +1490,12 @@ "Snake-Output": { "properties": { "spec": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Output" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Output" - }, - { - "$ref": "#/components/schemas/Mask-Output" - }, - { - "$ref": "#/components/schemas/Snake-Output" - }, - { - "$ref": "#/components/schemas/Concat-Output" - }, - { - "$ref": "#/components/schemas/Squash-Output" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Output" } ], - "title": "Spec", - "description": "The Spec to run in reverse every other iteration", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Output", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Output", - "Product": "#/components/schemas/Product-Output", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Output", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Output", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Output" - } - } + "description": "The Spec to run in reverse every other iteration" }, "type": { "type": "string", @@ -2659,6 +1515,104 @@ "title": "Snake", "description": "Run the Spec in reverse on every other iteration when nested.\n\nTypically created with the ``~`` operator.\n\n.. example_spec::\n\n from scanspec.specs import Line\n\n spec = Line(\"y\", 1, 3, 3) * ~Line(\"x\", 3, 5, 5)" }, + "Spec-Input": { + "oneOf": [ + { + "$ref": "#/components/schemas/Product-Input" + }, + { + "$ref": "#/components/schemas/Repeat" + }, + { + "$ref": "#/components/schemas/Zip-Input" + }, + { + "$ref": "#/components/schemas/Mask-Input" + }, + { + "$ref": "#/components/schemas/Snake-Input" + }, + { + "$ref": "#/components/schemas/Concat-Input" + }, + { + "$ref": "#/components/schemas/Squash-Input" + }, + { + "$ref": "#/components/schemas/Line" + }, + { + "$ref": "#/components/schemas/Static" + }, + { + "$ref": "#/components/schemas/Spiral" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "Concat": "#/components/schemas/Concat-Input", + "Line": "#/components/schemas/Line", + "Mask": "#/components/schemas/Mask-Input", + "Product": "#/components/schemas/Product-Input", + "Repeat": "#/components/schemas/Repeat", + "Snake": "#/components/schemas/Snake-Input", + "Spiral": "#/components/schemas/Spiral", + "Squash": "#/components/schemas/Squash-Input", + "Static": "#/components/schemas/Static", + "Zip": "#/components/schemas/Zip-Input" + } + } + }, + "Spec-Output": { + "oneOf": [ + { + "$ref": "#/components/schemas/Product-Output" + }, + { + "$ref": "#/components/schemas/Repeat" + }, + { + "$ref": "#/components/schemas/Zip-Output" + }, + { + "$ref": "#/components/schemas/Mask-Output" + }, + { + "$ref": "#/components/schemas/Snake-Output" + }, + { + "$ref": "#/components/schemas/Concat-Output" + }, + { + "$ref": "#/components/schemas/Squash-Output" + }, + { + "$ref": "#/components/schemas/Line" + }, + { + "$ref": "#/components/schemas/Static" + }, + { + "$ref": "#/components/schemas/Spiral" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "Concat": "#/components/schemas/Concat-Output", + "Line": "#/components/schemas/Line", + "Mask": "#/components/schemas/Mask-Output", + "Product": "#/components/schemas/Product-Output", + "Repeat": "#/components/schemas/Repeat", + "Snake": "#/components/schemas/Snake-Output", + "Spiral": "#/components/schemas/Spiral", + "Squash": "#/components/schemas/Squash-Output", + "Static": "#/components/schemas/Static", + "Zip": "#/components/schemas/Zip-Output" + } + } + }, "Spiral": { "properties": { "x_axis": { @@ -2728,55 +1682,12 @@ "Squash-Input": { "properties": { "spec": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Input" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Input" - }, - { - "$ref": "#/components/schemas/Mask-Input" - }, - { - "$ref": "#/components/schemas/Snake-Input" - }, - { - "$ref": "#/components/schemas/Concat-Input" - }, - { - "$ref": "#/components/schemas/Squash-Input" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Input" } ], - "title": "Spec", - "description": "The Spec to squash the dimensions of", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Input", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Input", - "Product": "#/components/schemas/Product-Input", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Input", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Input", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Input" - } - } + "description": "The Spec to squash the dimensions of" }, "check_path_changes": { "type": "boolean", @@ -2805,55 +1716,12 @@ "Squash-Output": { "properties": { "spec": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Output" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Output" - }, - { - "$ref": "#/components/schemas/Mask-Output" - }, - { - "$ref": "#/components/schemas/Snake-Output" - }, - { - "$ref": "#/components/schemas/Concat-Output" - }, - { - "$ref": "#/components/schemas/Squash-Output" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Output" } ], - "title": "Spec", - "description": "The Spec to squash the dimensions of", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Output", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Output", - "Product": "#/components/schemas/Product-Output", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Output", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Output", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Output" - } - } + "description": "The Spec to squash the dimensions of" }, "check_path_changes": { "type": "boolean", @@ -2919,106 +1787,20 @@ "SymmetricDifferenceOf-Input": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Input" - }, - { - "$ref": "#/components/schemas/UnionOf-Input" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Input" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Input" } ], - "title": "Left", - "description": "The left-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Input", - "DifferenceOf": "#/components/schemas/DifferenceOf-Input", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Input", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Input", - "UnionOf": "#/components/schemas/UnionOf-Input" - } - } + "description": "The left-hand Region to combine" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Input" - }, - { - "$ref": "#/components/schemas/UnionOf-Input" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Input" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Input" } ], - "title": "Right", - "description": "The right-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Input", - "DifferenceOf": "#/components/schemas/DifferenceOf-Input", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Input", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Input", - "UnionOf": "#/components/schemas/UnionOf-Input" - } - } + "description": "The right-hand Region to combine" }, "type": { "type": "string", @@ -3042,106 +1824,20 @@ "SymmetricDifferenceOf-Output": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Output" - }, - { - "$ref": "#/components/schemas/UnionOf-Output" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Output" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Output" } ], - "title": "Left", - "description": "The left-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Output", - "DifferenceOf": "#/components/schemas/DifferenceOf-Output", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Output", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Output", - "UnionOf": "#/components/schemas/UnionOf-Output" - } - } + "description": "The left-hand Region to combine" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Output" - }, - { - "$ref": "#/components/schemas/UnionOf-Output" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Output" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Output" } ], - "title": "Right", - "description": "The right-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Output", - "DifferenceOf": "#/components/schemas/DifferenceOf-Output", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Output", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Output", - "UnionOf": "#/components/schemas/UnionOf-Output" - } - } + "description": "The right-hand Region to combine" }, "type": { "type": "string", @@ -3165,106 +1861,20 @@ "UnionOf-Input": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Input" - }, - { - "$ref": "#/components/schemas/UnionOf-Input" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Input" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Input" } ], - "title": "Left", - "description": "The left-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Input", - "DifferenceOf": "#/components/schemas/DifferenceOf-Input", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Input", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Input", - "UnionOf": "#/components/schemas/UnionOf-Input" - } - } + "description": "The left-hand Region to combine" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Input" - }, - { - "$ref": "#/components/schemas/UnionOf-Input" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Input" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Input" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Input" } ], - "title": "Right", - "description": "The right-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Input", - "DifferenceOf": "#/components/schemas/DifferenceOf-Input", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Input", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Input", - "UnionOf": "#/components/schemas/UnionOf-Input" - } - } + "description": "The right-hand Region to combine" }, "type": { "type": "string", @@ -3288,106 +1898,20 @@ "UnionOf-Output": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Output" - }, - { - "$ref": "#/components/schemas/UnionOf-Output" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Output" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Output" } ], - "title": "Left", - "description": "The left-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Output", - "DifferenceOf": "#/components/schemas/DifferenceOf-Output", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Output", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Output", - "UnionOf": "#/components/schemas/UnionOf-Output" - } - } + "description": "The left-hand Region to combine" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/CombinationOf-Output" - }, - { - "$ref": "#/components/schemas/UnionOf-Output" - }, - { - "$ref": "#/components/schemas/IntersectionOf-Output" - }, - { - "$ref": "#/components/schemas/DifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/SymmetricDifferenceOf-Output" - }, - { - "$ref": "#/components/schemas/Range" - }, - { - "$ref": "#/components/schemas/Rectangle" - }, - { - "$ref": "#/components/schemas/Polygon" - }, - { - "$ref": "#/components/schemas/Circle" - }, + "allOf": [ { - "$ref": "#/components/schemas/Ellipse" + "$ref": "#/components/schemas/Region-Output" } ], - "title": "Right", - "description": "The right-hand Region to combine", - "discriminator": { - "propertyName": "type", - "mapping": { - "Circle": "#/components/schemas/Circle", - "CombinationOf": "#/components/schemas/CombinationOf-Output", - "DifferenceOf": "#/components/schemas/DifferenceOf-Output", - "Ellipse": "#/components/schemas/Ellipse", - "IntersectionOf": "#/components/schemas/IntersectionOf-Output", - "Polygon": "#/components/schemas/Polygon", - "Range": "#/components/schemas/Range", - "Rectangle": "#/components/schemas/Rectangle", - "SymmetricDifferenceOf": "#/components/schemas/SymmetricDifferenceOf-Output", - "UnionOf": "#/components/schemas/UnionOf-Output" - } - } + "description": "The right-hand Region to combine" }, "type": { "type": "string", @@ -3411,106 +1935,20 @@ "ValidResponse": { "properties": { "input_spec": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Output" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Output" - }, - { - "$ref": "#/components/schemas/Mask-Output" - }, - { - "$ref": "#/components/schemas/Snake-Output" - }, - { - "$ref": "#/components/schemas/Concat-Output" - }, - { - "$ref": "#/components/schemas/Squash-Output" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Output" } ], - "title": "Input Spec", - "description": "The input scanspec", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Output", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Output", - "Product": "#/components/schemas/Product-Output", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Output", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Output", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Output" - } - } + "description": "The input scanspec" }, "valid_spec": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Output" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Output" - }, - { - "$ref": "#/components/schemas/Mask-Output" - }, - { - "$ref": "#/components/schemas/Snake-Output" - }, - { - "$ref": "#/components/schemas/Concat-Output" - }, - { - "$ref": "#/components/schemas/Squash-Output" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Output" } ], - "title": "Valid Spec", - "description": "The validated version of the spec", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Output", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Output", - "Product": "#/components/schemas/Product-Output", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Output", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Output", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Output" - } - } + "description": "The validated version of the spec" } }, "type": "object", @@ -3557,106 +1995,20 @@ "Zip-Input": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Input" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Input" - }, - { - "$ref": "#/components/schemas/Mask-Input" - }, - { - "$ref": "#/components/schemas/Snake-Input" - }, - { - "$ref": "#/components/schemas/Concat-Input" - }, - { - "$ref": "#/components/schemas/Squash-Input" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Input" } ], - "title": "Left", - "description": "The left-hand Spec to Zip, will appear earlier in axes", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Input", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Input", - "Product": "#/components/schemas/Product-Input", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Input", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Input", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Input" - } - } + "description": "The left-hand Spec to Zip, will appear earlier in axes" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Input" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Input" - }, - { - "$ref": "#/components/schemas/Mask-Input" - }, - { - "$ref": "#/components/schemas/Snake-Input" - }, - { - "$ref": "#/components/schemas/Concat-Input" - }, - { - "$ref": "#/components/schemas/Squash-Input" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Input" } ], - "title": "Right", - "description": "The right-hand Spec to Zip, will appear later in axes", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Input", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Input", - "Product": "#/components/schemas/Product-Input", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Input", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Input", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Input" - } - } + "description": "The right-hand Spec to Zip, will appear later in axes" }, "type": { "type": "string", @@ -3680,106 +2032,20 @@ "Zip-Output": { "properties": { "left": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Output" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Output" - }, - { - "$ref": "#/components/schemas/Mask-Output" - }, - { - "$ref": "#/components/schemas/Snake-Output" - }, - { - "$ref": "#/components/schemas/Concat-Output" - }, - { - "$ref": "#/components/schemas/Squash-Output" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Output" } ], - "title": "Left", - "description": "The left-hand Spec to Zip, will appear earlier in axes", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Output", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Output", - "Product": "#/components/schemas/Product-Output", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Output", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Output", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Output" - } - } + "description": "The left-hand Spec to Zip, will appear earlier in axes" }, "right": { - "oneOf": [ - { - "$ref": "#/components/schemas/Product-Output" - }, - { - "$ref": "#/components/schemas/Repeat" - }, - { - "$ref": "#/components/schemas/Zip-Output" - }, - { - "$ref": "#/components/schemas/Mask-Output" - }, - { - "$ref": "#/components/schemas/Snake-Output" - }, - { - "$ref": "#/components/schemas/Concat-Output" - }, - { - "$ref": "#/components/schemas/Squash-Output" - }, - { - "$ref": "#/components/schemas/Line" - }, - { - "$ref": "#/components/schemas/Static" - }, + "allOf": [ { - "$ref": "#/components/schemas/Spiral" + "$ref": "#/components/schemas/Spec-Output" } ], - "title": "Right", - "description": "The right-hand Spec to Zip, will appear later in axes", - "discriminator": { - "propertyName": "type", - "mapping": { - "Concat": "#/components/schemas/Concat-Output", - "Line": "#/components/schemas/Line", - "Mask": "#/components/schemas/Mask-Output", - "Product": "#/components/schemas/Product-Output", - "Repeat": "#/components/schemas/Repeat", - "Snake": "#/components/schemas/Snake-Output", - "Spiral": "#/components/schemas/Spiral", - "Squash": "#/components/schemas/Squash-Output", - "Static": "#/components/schemas/Static", - "Zip": "#/components/schemas/Zip-Output" - } - } + "description": "The right-hand Spec to Zip, will appear later in axes" }, "type": { "type": "string", diff --git a/src/scanspec/core.py b/src/scanspec/core.py index 39f2a57a..eac6c938 100644 --- a/src/scanspec/core.py +++ b/src/scanspec/core.py @@ -1,28 +1,20 @@ from __future__ import annotations -import dataclasses from collections.abc import Callable, Iterable, Iterator, Sequence -from functools import partial -from inspect import isclass +from functools import lru_cache from typing import ( Any, Generic, Literal, TypeVar, - Union, get_origin, get_type_hints, ) import numpy as np -from pydantic import ( - ConfigDict, - Field, - GetCoreSchemaHandler, - TypeAdapter, -) -from pydantic.dataclasses import rebuild_dataclass -from pydantic.fields import FieldInfo +from pydantic import BaseModel, ConfigDict, Field, GetCoreSchemaHandler +from pydantic.dataclasses import is_pydantic_dataclass, rebuild_dataclass +from pydantic_core.core_schema import tagged_union_schema __all__ = [ "if_instance_do", @@ -43,13 +35,13 @@ def discriminated_union_of_subclasses( - cls, + super_cls: type, discriminator: str = "type", -): +) -> type: """Add all subclasses of super_cls to a discriminated union. For all subclasses of super_cls, add a discriminator field to identify - the type. Raw JSON should look like {"type": , params for + the type. Raw JSON should look like {: , params for ...}. Example:: @@ -104,134 +96,104 @@ def calculate(self) -> int: ) Args: - super_cls: The superclass of the union, Expression in the above example + cls: The superclass of the union, Expression in the above example discriminator: The discriminator that will be inserted into the serialized documents for type determination. Defaults to "type". - config: A pydantic config class to be inserted into all - subclasses. Defaults to None. Returns: - Type | Callable[[Type], Type]: A decorator that adds the necessary - functionality to a class. + Type: decorated superclass with handling for subclasses to be added + to its discriminated union for deserialization """ - tagged_union = _TaggedUnion(cls, discriminator) - _tagged_unions[cls] = tagged_union - cls.__init_subclass__ = classmethod(partial(__init_subclass__, discriminator)) - cls.__get_pydantic_core_schema__ = classmethod( - partial(__get_pydantic_core_schema__, tagged_union=tagged_union) - ) - return cls + tagged_union = _TaggedUnion(super_cls, discriminator) + _tagged_unions[super_cls] = tagged_union + + def add_subclass_to_union(subclass): + # Add a discriminator field to a subclass so it can + # be identified when deserializing + subclass.__annotations__ = { + **subclass.__annotations__, + discriminator: Literal[subclass.__name__], # type: ignore + } + setattr(subclass, discriminator, Field(subclass.__name__, repr=False)) # type: ignore + def get_schema_of_union(cls, source_type: Any, handler: GetCoreSchemaHandler): + if cls is not super_cls: + tagged_union.add_member(cls) + return handler(cls) + # Rebuild any dataclass (including this one) that references this union + # Note that this has to be done after the creation of the dataclass so that + # previously created classes can refer to this newly created class + return tagged_union.schema(handler) -T = TypeVar("T", type, Callable) + super_cls.__init_subclass__ = classmethod(add_subclass_to_union) # type: ignore + super_cls.__get_pydantic_core_schema__ = classmethod(get_schema_of_union) # type: ignore + return super_cls -def deserialize_as(cls, obj): - return _tagged_unions[cls].type_adapter.validate_python(obj) +T = TypeVar("T", type, Callable) def uses_tagged_union(cls_or_func: T) -> T: """ - Decorator that processes the type hints of a class or function to detect and - register any tagged unions. If a tagged union is detected in the type hints, - it registers the class or function as a referrer to that tagged union. - Args: - cls_or_func (T): The class or function to be processed for tagged unions. - Returns: - T: The original class or function, unmodified. + T = TypeVar("T", type, Callable) + Decorator that processes the type hints of a class or function to detect and + register any tagged unions. If a tagged union is detected in the type hints, + it registers the class or function as a referrer to that tagged union. + Args: + cls_or_func (T): The class or function to be processed for tagged unions. + Returns: + T: The original class or function, unmodified. """ - for k, v in get_type_hints(cls_or_func).items(): + for v in get_type_hints(cls_or_func).values(): tagged_union = _tagged_unions.get(get_origin(v) or v, None) if tagged_union: - tagged_union.add_referrer(cls_or_func, k) + tagged_union.add_reference(cls_or_func) return cls_or_func +_tagged_unions: dict[type, _TaggedUnion] = {} + + class _TaggedUnion: def __init__(self, base_class: type, discriminator: str): self._base_class = base_class - # The members of the tagged union, i.e. subclasses of the baseclasses - self._members: list[type] = [] # Classes and their field names that refer to this tagged union - self._referrers: dict[type | Callable, set[str]] = {} - self.type_adapter: TypeAdapter = TypeAdapter(None) self._discriminator = discriminator - - def _make_union(self): - if len(self._members) > 0: - return Union[tuple(self._members)] # type: ignore # noqa - - def _set_discriminator(self, cls: type | Callable, field_name: str, field: Any): - # Set the field to use the `type` discriminator on deserialize - # https://docs.pydantic.dev/2.8/concepts/unions/#discriminated-unions-with-str-discriminators - if isclass(cls): - assert isinstance( - field, FieldInfo - ), f"Expected {cls.__name__}.{field_name} to be a Pydantic field, not {field!r}" # noqa: E501 - field.discriminator = self._discriminator + # The members of the tagged union, i.e. subclasses of the baseclass + self._members: list[type] = [] + self._references: set[type] = set() def add_member(self, cls: type): if cls in self._members: - # A side effect of hooking to __get_pydantic_core_schema__ is that it is - # called muliple times for the same member, do no process if it wouldn't - # change the member list return - self._members.append(cls) - union = self._make_union() - if union: - # There are more than 1 subclasses in the union, so set all the referrers - # to use this union - for referrer, fields in self._referrers.items(): - if isclass(referrer): - for field in dataclasses.fields(referrer): - if field.name in fields: - field.type = union - self._set_discriminator(referrer, field.name, field.default) - rebuild_dataclass(referrer, force=True) - # Make a type adapter for use in deserialization - self.type_adapter = TypeAdapter(union) - - def add_referrer(self, cls: type | Callable, attr_name: str): - self._referrers.setdefault(cls, set()).add(attr_name) - union = self._make_union() - if union: - # There are more than 1 subclasses in the union, so set the referrer - # (which is currently being constructed) to use it - # note that we use annotations as the class has not been turned into - # a dataclass yet - cls.__annotations__[attr_name] = union - self._set_discriminator(cls, attr_name, getattr(cls, attr_name, None)) - - -_tagged_unions: dict[type, _TaggedUnion] = {} - - -def __init_subclass__(discriminator: str, cls: type): - # Add a discriminator field to the class so it can - # be identified when deserailizing, and make sure it is last in the list - cls.__annotations__ = { - **cls.__annotations__, - discriminator: Literal[cls.__name__], # type: ignore - } - cls.type = Field(cls.__name__, repr=False) # type: ignore - # Replace any bare annotation with a discriminated union of subclasses - # and register this class as one that refers to that union so it can be updated - for k, v in get_type_hints(cls).items(): - # This works for Expression[T] or Expression - tagged_union = _tagged_unions.get(get_origin(v) or v, None) - if tagged_union: - tagged_union.add_referrer(cls, k) + for member in self._members: + if member is not cls: + _TaggedUnion._rebuild(member) + for ref in self._references: + _TaggedUnion._rebuild(ref) + + def add_reference(self, cls: type): + self._references.add(cls) + + @staticmethod + def _rebuild(cls): + if is_pydantic_dataclass(cls): + rebuild_dataclass(cls, force=True) + if issubclass(cls, BaseModel): + cls.model_rebuild(force=True) + + def schema(self, handler): + return tagged_union_schema( + make_schema(tuple(self._members), handler), + discriminator=self._discriminator, + ref=self._base_class.__name__, + ) -def __get_pydantic_core_schema__( - cls, source_type: Any, handler: GetCoreSchemaHandler, tagged_union: _TaggedUnion -): - # Rebuild any dataclass (including this one) that references this union - # Note that this has to be done after the creation of the dataclass so that - # previously created classes can refer to this newly created class - tagged_union.add_member(cls) - return handler(source_type) +@lru_cache(1) +def make_schema(members: tuple[type, ...], handler): + return {member.__name__: handler(member) for member in members} def if_instance_do(x: Any, cls: type, func: Callable): diff --git a/src/scanspec/plot.py b/src/scanspec/plot.py index 0ee4419f..43311663 100644 --- a/src/scanspec/plot.py +++ b/src/scanspec/plot.py @@ -8,7 +8,7 @@ from mpl_toolkits.mplot3d import Axes3D, proj3d from scipy import interpolate -from .core import Path, uses_tagged_union +from .core import Path from .regions import Circle, Ellipse, Polygon, Rectangle, Region, find_regions from .specs import DURATION, Spec @@ -86,7 +86,6 @@ def _plot_spline(axes, ranges, arrays: list[np.ndarray], index_colours: dict[int yield unscaled_splines -@uses_tagged_union def plot_spec(spec: Spec[Any], title: str | None = None): """Plot a spec, drawing the path taken through the scan. diff --git a/src/scanspec/regions.py b/src/scanspec/regions.py index 0c9b0b1f..e60a3494 100644 --- a/src/scanspec/regions.py +++ b/src/scanspec/regions.py @@ -1,18 +1,17 @@ from __future__ import annotations from collections.abc import Iterator, Mapping -from dataclasses import asdict, is_dataclass +from dataclasses import is_dataclass from typing import Any, Generic import numpy as np -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, TypeAdapter from pydantic.dataclasses import dataclass from .core import ( AxesPoints, Axis, StrictConfig, - deserialize_as, discriminated_union_of_subclasses, if_instance_do, ) @@ -68,12 +67,12 @@ def __xor__(self, other) -> SymmetricDifferenceOf[Axis]: def serialize(self) -> Mapping[str, Any]: """Serialize the Region to a dictionary.""" - return asdict(self) # type: ignore + return TypeAdapter(Region).dump_python(self) @staticmethod - def deserialize(obj): - """Deserialize the Region from a dictionary.""" - return deserialize_as(Region, obj) + def deserialize(obj) -> Region: + """Deserialize a Region from a dictionary.""" + return TypeAdapter(Region).validate_python(obj) def get_mask(region: Region[Axis], points: AxesPoints[Axis]) -> np.ndarray: diff --git a/src/scanspec/service.py b/src/scanspec/service.py index e52ef5d9..ac8a147f 100644 --- a/src/scanspec/service.py +++ b/src/scanspec/service.py @@ -11,7 +11,7 @@ from pydantic import Field from pydantic.dataclasses import dataclass -from scanspec.core import AxesPoints, Frames, Path, uses_tagged_union +from scanspec.core import AxesPoints, Frames, Path from .specs import Line, Spec @@ -27,7 +27,6 @@ @dataclass -@uses_tagged_union class ValidResponse: """Response model for spec validation.""" @@ -44,7 +43,6 @@ class PointsFormat(str, Enum): @dataclass -@uses_tagged_union class PointsRequest: """A request for generated scan points.""" @@ -125,7 +123,6 @@ class SmallestStepResponse: @app.post("/valid", response_model=ValidResponse) -@uses_tagged_union def valid( spec: Spec = Body(..., examples=[_EXAMPLE_SPEC]), ) -> ValidResponse | JSONResponse: @@ -198,7 +195,6 @@ def bounds( @app.post("/gap", response_model=GapResponse) -@uses_tagged_union def gap( spec: Spec = Body( ..., @@ -224,7 +220,6 @@ def gap( @app.post("/smalleststep", response_model=SmallestStepResponse) -@uses_tagged_union def smallest_step( spec: Spec = Body(..., examples=[_EXAMPLE_SPEC]), ) -> SmallestStepResponse: diff --git a/src/scanspec/specs.py b/src/scanspec/specs.py index d51e5a6f..a9e4d648 100644 --- a/src/scanspec/specs.py +++ b/src/scanspec/specs.py @@ -1,14 +1,13 @@ from __future__ import annotations from collections.abc import Callable, Mapping -from dataclasses import asdict from typing import ( Any, Generic, ) import numpy as np -from pydantic import Field, validate_call +from pydantic import Field, TypeAdapter, validate_call from pydantic.dataclasses import dataclass from .core import ( @@ -18,7 +17,6 @@ Path, SnakedFrames, StrictConfig, - deserialize_as, discriminated_union_of_subclasses, gap_between_frames, if_instance_do, @@ -107,13 +105,13 @@ def concat(self, other: Spec) -> Concat[Axis]: return Concat(self, other) def serialize(self) -> Mapping[str, Any]: - """Serialize the spec to a dictionary.""" - return asdict(self) # type: ignore + """Serialize the Spec to a dictionary.""" + return TypeAdapter(Spec).dump_python(self) @staticmethod - def deserialize(obj): - """Deserialize the spec from a dictionary.""" - return deserialize_as(Spec, obj) + def deserialize(obj) -> Spec: + """Deserialize a Spec from a dictionary.""" + return TypeAdapter(Spec).validate_python(obj) @dataclass(config=StrictConfig) diff --git a/tests/test_basemodel.py b/tests/test_basemodel.py new file mode 100644 index 00000000..85d83741 --- /dev/null +++ b/tests/test_basemodel.py @@ -0,0 +1,56 @@ +import pytest +from pydantic import BaseModel, TypeAdapter +from pydantic.dataclasses import dataclass + +from scanspec.core import StrictConfig, uses_tagged_union +from scanspec.specs import Line, Spec + + +@uses_tagged_union +class Foo(BaseModel): + spec: Spec + + +simple_foo = Foo(spec=Line("x", 1, 2, 5)) +nested_foo = Foo(spec=Line("x", 1, 2, 5) * Line("y", 1, 2, 5)) + + +@pytest.mark.parametrize("model", [simple_foo, nested_foo]) +def test_model_validation(model: Foo): + # To/from Python dict + as_dict = model.model_dump() + deserialized = Foo.model_validate(as_dict) + assert deserialized == model + + # To/from Json dict + as_json = model.model_dump_json() + deserialized = Foo.model_validate_json(as_json) + assert deserialized == model + + +@pytest.mark.parametrize("model", [simple_foo, nested_foo]) +def test_type_adapter(model: Foo): + type_adapter = TypeAdapter(Foo) + + # To/from Python dict + as_dict = model.model_dump() + deserialized = type_adapter.validate_python(as_dict) + assert deserialized == model + + # To/from Json dict + as_json = model.model_dump_json() + deserialized = type_adapter.validate_json(as_json) + assert deserialized == model + + +def test_schema_updates_with_new_values(): + old_schema = TypeAdapter(Foo).json_schema() + + @dataclass(config=StrictConfig) + class Splat(Spec[str]): # NOSONAR + def axes(self) -> list[str]: + return ["*"] + + new_schema = TypeAdapter(Foo).json_schema() + + assert new_schema != old_schema diff --git a/tests/test_serialization.py b/tests/test_serialization.py index 89c2e7d7..d10dc3bf 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -2,7 +2,7 @@ from typing import Any import pytest -from pydantic import ValidationError +from pydantic import TypeAdapter, ValidationError from scanspec.regions import Circle, Rectangle, Region, UnionOf from scanspec.specs import Line, Mask, Spec, Spiral @@ -160,3 +160,18 @@ def test_complex_nested_serializes() -> None: def test_detects_invalid_serialized(serialized: Mapping[str, Any]) -> None: with pytest.raises(ValidationError): Spec.deserialize(serialized) + + +def test_vanilla_serialization(): + ob = Mask( + Spiral.spaced("x", "y", 0, 0, 10, 3), + UnionOf( + Circle("x", "y", x_middle=0, y_middle=1, radius=4), + Rectangle("x", "y", 0, 1.1, 1.5, 2.1, 30), + ), + ) + + adapter = TypeAdapter(Spec) + serialized = adapter.dump_json(ob) + deserialized = adapter.validate_json(serialized) + assert deserialized == ob