From 77b40b049b9c75209859c93b88d6907c4b2b0443 Mon Sep 17 00:00:00 2001 From: lostbean Date: Mon, 2 Dec 2024 15:39:33 -0300 Subject: [PATCH] do not use oneOf for single constructor data type --- src/json/blueprint.gleam | 25 ++++++++++++++++++------- test/json_blueprint_test.gleam | 7 +++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/json/blueprint.gleam b/src/json/blueprint.gleam index 924215e..ec0ffac 100644 --- a/src/json/blueprint.gleam +++ b/src/json/blueprint.gleam @@ -184,18 +184,29 @@ pub fn union_type_decoder( |> result.flatten } - #( - enum_decoder, - list.map(decoders, fn(field_dec) { - let #(name, dec) = field_dec + let schema = case decoders { + [] -> jsch.Object([], Some(False), None) + + [#(name, dec)] -> jsch.Object( [#("type", jsch.Enum([json.string(name)])), #("data", dec.1)], Some(False), Some(["type", "data"]), ) - }) - |> jsch.OneOf, - ) + + xs -> + list.map(xs, fn(field_dec) { + let #(name, dec) = field_dec + jsch.Object( + [#("type", jsch.Enum([json.string(name)])), #("data", dec.1)], + Some(False), + Some(["type", "data"]), + ) + }) + |> jsch.OneOf + } + + #(enum_decoder, schema) } /// Function to encode an enum type (unions where constructors have no arguments) into a JSON object. diff --git a/test/json_blueprint_test.gleam b/test/json_blueprint_test.gleam index b30adc5..3e031be 100644 --- a/test/json_blueprint_test.gleam +++ b/test/json_blueprint_test.gleam @@ -659,4 +659,11 @@ pub fn drawing_test() { "{\"type\":\"box\",\"data\":{\"width\":15.0}}" |> blueprint.decode(using: drawing_decoder()) |> should.be_error() + + drawing_decoder() + |> blueprint.generate_json_schema + |> json.to_string + |> should.equal( + "{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"required\":[\"type\",\"data\"],\"additionalProperties\":false,\"type\":\"object\",\"properties\":{\"type\":{\"enum\":[\"box\"]},\"data\":{\"required\":[\"width\",\"height\",\"position\"],\"additionalProperties\":false,\"type\":\"object\",\"properties\":{\"width\":{\"type\":\"number\"},\"height\":{\"type\":\"number\"},\"position\":{\"maxItems\":2,\"minItems\":2,\"prefixItems\":[{\"type\":\"number\"},{\"type\":\"number\"}]},\"color\":{\"required\":[\"enum\"],\"additionalProperties\":false,\"type\":\"object\",\"properties\":{\"enum\":{\"enum\":[\"red\",\"green\",\"blue\"]}}}}}}}", + ) }