quicktype
quicktype copied to clipboard
Generated C# code doesn't seem to consider allOf
I am trying to generate C# code for a schema with conditional subschemas, that I'm expressing with allOf and if, but I cannot find those conditional subschemas in the output source code.
We can reproduce it by running the example in the JSON Schema documentation through QuickType:
{
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"country": {
"default": "United States of America",
"enum": ["United States of America", "Canada"]
}
},
"if": {
"properties": { "country": { "const": "United States of America" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
},
"else": {
"properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
}
}
The resulting C# output does not contain any reference to postal_code:
// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using QuickType;
//
// var test = Test.FromJson(jsonString);
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class Test
{
[JsonProperty("country", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
public virtual Country? Country { get; set; }
[JsonProperty("street_address", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
public virtual string StreetAddress { get; set; }
}
public enum Country { Canada, Netherlands, UnitedStatesOfAmerica };
public partial class Test
{
public static Test FromJson(string json) => JsonConvert.DeserializeObject<Test>(json, QuickType.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this Test self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
CountryConverter.Singleton,
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
internal class CountryConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(Country) || t == typeof(Country?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
switch (value)
{
case "Canada":
return Country.Canada;
case "Netherlands":
return Country.Netherlands;
case "United States of America":
return Country.UnitedStatesOfAmerica;
}
throw new Exception("Cannot unmarshal type Country");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (Country)untypedValue;
switch (value)
{
case Country.Canada:
serializer.Serialize(writer, "Canada");
return;
case Country.Netherlands:
serializer.Serialize(writer, "Netherlands");
return;
case Country.UnitedStatesOfAmerica:
serializer.Serialize(writer, "United States of America");
return;
}
throw new Exception("Cannot marshal type Country");
}
public static readonly CountryConverter Singleton = new CountryConverter();
}
}
The same happens if I quickly inspect code generated in other languages such as golang:
// This file was generated from JSON Schema using quicktype, do not modify it directly.
// To parse and unparse this JSON data, add this code to your project and do:
//
// test, err := UnmarshalTest(bytes)
// bytes, err = test.Marshal()
package main
import "encoding/json"
func UnmarshalTest(data []byte) (Test, error) {
var r Test
err := json.Unmarshal(data, &r)
return r, err
}
func (r *Test) Marshal() ([]byte, error) {
return json.Marshal(r)
}
type Test struct {
Country *Country `json:"country,omitempty"`
StreetAddress *string `json:"street_address,omitempty"`
}
type Country string
const (
Canada Country = "Canada"
Netherlands Country = "Netherlands"
UnitedStatesOfAmerica Country = "United States of America"
lol, expecting conditional subschemas to work on a project with 400+ issues