Generated-output differences

quicktype output changed between the PR base and tested PR merge revisions.
← Back to the pull request
1test cases
20files differ
0modified
20new
0deleted
2,844changed lines
+2,844 −0insertions / deletions
Base a49b94e8f6f1b319a4da9fb15d57ef13ba316ddc · PR merge 6c8d4f72959eb1073bb1bd46bc3d5e4bc24c8519 · Head 719145d88e3e32c5dc70dfa99486b707f48addcf · raw patch
Test case

test/inputs/schema/issue-1833

20 generated files · +2,844 −0
Aschema-cplusplusdefault / quicktype.hpp+163 −0
@@ -0,0 +1,163 @@
1+// To parse this JSON data, first install
2+//
3+// json.hpp https://github.com/nlohmann/json
4+//
5+// Then include this file, and then do
6+//
7+// A data = nlohmann::json::parse(jsonString);
8+// B data = nlohmann::json::parse(jsonString);
9+// C data = nlohmann::json::parse(jsonString);
10+// TopLevel data = nlohmann::json::parse(jsonString);
11+
12+#pragma once
13+
14+#include "json.hpp"
15+
16+#include <optional>
17+#include <stdexcept>
18+#include <regex>
19+
20+namespace quicktype {
21+ using nlohmann::json;
22+
23+ #ifndef NLOHMANN_UNTYPED_quicktype_HELPER
24+ #define NLOHMANN_UNTYPED_quicktype_HELPER
25+ inline json get_untyped(const json & j, const char * property) {
26+ if (j.find(property) != j.end()) {
27+ return j.at(property).get<json>();
28+ }
29+ return json();
30+ }
31+
32+ inline json get_untyped(const json & j, std::string property) {
33+ return get_untyped(j, property.data());
34+ }
35+ #endif
36+
37+ class C {
38+ public:
39+ C() = default;
40+ virtual ~C() = default;
41+
42+ private:
43+ std::string name;
44+
45+ public:
46+ const std::string & get_name() const { return name; }
47+ std::string & get_mutable_name() { return name; }
48+ void set_name(const std::string & value) { this->name = value; }
49+ };
50+
51+ class A {
52+ public:
53+ A() = default;
54+ virtual ~A() = default;
55+
56+ private:
57+ std::vector<C> in;
58+ std::string name;
59+
60+ public:
61+ const std::vector<C> & get_in() const { return in; }
62+ std::vector<C> & get_mutable_in() { return in; }
63+ void set_in(const std::vector<C> & value) { this->in = value; }
64+
65+ const std::string & get_name() const { return name; }
66+ std::string & get_mutable_name() { return name; }
67+ void set_name(const std::string & value) { this->name = value; }
68+ };
69+
70+ class B {
71+ public:
72+ B() = default;
73+ virtual ~B() = default;
74+
75+ private:
76+ std::string name;
77+ std::vector<C> out;
78+
79+ public:
80+ const std::string & get_name() const { return name; }
81+ std::string & get_mutable_name() { return name; }
82+ void set_name(const std::string & value) { this->name = value; }
83+
84+ const std::vector<C> & get_out() const { return out; }
85+ std::vector<C> & get_mutable_out() { return out; }
86+ void set_out(const std::vector<C> & value) { this->out = value; }
87+ };
88+
89+ class TopLevel {
90+ public:
91+ TopLevel() = default;
92+ virtual ~TopLevel() = default;
93+
94+ private:
95+ A a;
96+ B b;
97+
98+ public:
99+ const A & get_a() const { return a; }
100+ A & get_mutable_a() { return a; }
101+ void set_a(const A & value) { this->a = value; }
102+
103+ const B & get_b() const { return b; }
104+ B & get_mutable_b() { return b; }
105+ void set_b(const B & value) { this->b = value; }
106+ };
107+}
108+
109+namespace quicktype {
110+ void from_json(const json & j, C & x);
111+ void to_json(json & j, const C & x);
112+
113+ void from_json(const json & j, A & x);
114+ void to_json(json & j, const A & x);
115+
116+ void from_json(const json & j, B & x);
117+ void to_json(json & j, const B & x);
118+
119+ void from_json(const json & j, TopLevel & x);
120+ void to_json(json & j, const TopLevel & x);
121+
122+ inline void from_json(const json & j, C& x) {
123+ x.set_name(j.at("name").get<std::string>());
124+ }
125+
126+ inline void to_json(json & j, const C & x) {
127+ j = json::object();
128+ j["name"] = x.get_name();
129+ }
130+
131+ inline void from_json(const json & j, A& x) {
132+ x.set_in(j.at("in").get<std::vector<C>>());
133+ x.set_name(j.at("name").get<std::string>());
134+ }
135+
136+ inline void to_json(json & j, const A & x) {
137+ j = json::object();
138+ j["in"] = x.get_in();
139+ j["name"] = x.get_name();
140+ }
141+
142+ inline void from_json(const json & j, B& x) {
143+ x.set_name(j.at("name").get<std::string>());
144+ x.set_out(j.at("out").get<std::vector<C>>());
145+ }
146+
147+ inline void to_json(json & j, const B & x) {
148+ j = json::object();
149+ j["name"] = x.get_name();
150+ j["out"] = x.get_out();
151+ }
152+
153+ inline void from_json(const json & j, TopLevel& x) {
154+ x.set_a(j.at("a").get<A>());
155+ x.set_b(j.at("b").get<B>());
156+ }
157+
158+ inline void to_json(json & j, const TopLevel & x) {
159+ j = json::object();
160+ j["a"] = x.get_a();
161+ j["b"] = x.get_b();
162+ }
163+}
Aschema-csharp-recordsdefault / QuickType.cs+109 −0
@@ -0,0 +1,109 @@
1+// <auto-generated />
2+//
3+// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do one of these:
4+//
5+// using QuickType;
6+//
7+// var a = A.FromJson(jsonString);
8+// var b = B.FromJson(jsonString);
9+// var c = C.FromJson(jsonString);
10+// var topLevel = TopLevel.FromJson(jsonString);
11+#nullable enable
12+#pragma warning disable CS8618
13+#pragma warning disable CS8601
14+#pragma warning disable CS8602
15+#pragma warning disable CS8603
16+#pragma warning disable CS8604
17+#pragma warning disable CS8625
18+#pragma warning disable CS8765
19+
20+namespace QuickType
21+{
22+ using System;
23+ using System.Collections.Generic;
24+
25+ using System.Globalization;
26+ using Newtonsoft.Json;
27+ using Newtonsoft.Json.Converters;
28+
29+ public partial record TopLevel
30+ {
31+ [JsonProperty("a", Required = Required.Always)]
32+ public A A { get; set; }
33+
34+ [JsonProperty("b", Required = Required.Always)]
35+ public B B { get; set; }
36+ }
37+
38+ public partial record A
39+ {
40+ [JsonProperty("in", Required = Required.Always)]
41+ public C[] In { get; set; }
42+
43+ [JsonProperty("name", Required = Required.Always)]
44+ public string Name { get; set; }
45+ }
46+
47+ public partial record C
48+ {
49+ [JsonProperty("name", Required = Required.Always)]
50+ public string Name { get; set; }
51+ }
52+
53+ public partial record B
54+ {
55+ [JsonProperty("name", Required = Required.Always)]
56+ public string Name { get; set; }
57+
58+ [JsonProperty("out", Required = Required.Always)]
59+ public C[] Out { get; set; }
60+ }
61+
62+ public partial record A
63+ {
64+ public static A FromJson(string json) => JsonConvert.DeserializeObject<A>(json, QuickType.Converter.Settings);
65+ }
66+
67+ public partial record B
68+ {
69+ public static B FromJson(string json) => JsonConvert.DeserializeObject<B>(json, QuickType.Converter.Settings);
70+ }
71+
72+ public partial record C
73+ {
74+ public static C FromJson(string json) => JsonConvert.DeserializeObject<C>(json, QuickType.Converter.Settings);
75+ }
76+
77+ public partial record TopLevel
78+ {
79+ public static TopLevel FromJson(string json) => JsonConvert.DeserializeObject<TopLevel>(json, QuickType.Converter.Settings);
80+ }
81+
82+ public static partial class Serialize
83+ {
84+ public static string ToJson(this A self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
85+ public static string ToJson(this B self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
86+ public static string ToJson(this C self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
87+ public static string ToJson(this TopLevel self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
88+ }
89+
90+ internal static partial class Converter
91+ {
92+ public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
93+ {
94+ MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
95+ DateParseHandling = DateParseHandling.None,
96+ Converters =
97+ {
98+ new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
99+ },
100+ };
101+ }
102+}
103+#pragma warning restore CS8618
104+#pragma warning restore CS8601
105+#pragma warning restore CS8602
106+#pragma warning restore CS8603
107+#pragma warning restore CS8604
108+#pragma warning restore CS8625
109+#pragma warning restore CS8765
Aschema-csharp-SystemTextJsondefault / QuickType.cs+220 −0
@@ -0,0 +1,220 @@
1+// <auto-generated />
2+//
3+// To parse this JSON data, add NuGet 'System.Text.Json' then do one of these:
4+//
5+// using QuickType;
6+//
7+// var a = A.FromJson(jsonString);
8+// var b = B.FromJson(jsonString);
9+// var c = C.FromJson(jsonString);
10+// var topLevel = TopLevel.FromJson(jsonString);
11+#nullable enable
12+#pragma warning disable CS8618
13+#pragma warning disable CS8601
14+#pragma warning disable CS8602
15+#pragma warning disable CS8603
16+
17+namespace QuickType
18+{
19+ using System;
20+ using System.Collections.Generic;
21+
22+ using System.Text.Json;
23+ using System.Text.Json.Serialization;
24+ using System.Globalization;
25+
26+ public partial class TopLevel
27+ {
28+ [JsonRequired]
29+ [JsonPropertyName("a")]
30+ public A A { get; set; }
31+
32+ [JsonRequired]
33+ [JsonPropertyName("b")]
34+ public B B { get; set; }
35+ }
36+
37+ public partial class A
38+ {
39+ [JsonRequired]
40+ [JsonPropertyName("in")]
41+ public C[] In { get; set; }
42+
43+ [JsonRequired]
44+ [JsonPropertyName("name")]
45+ public string Name { get; set; }
46+ }
47+
48+ public partial class C
49+ {
50+ [JsonRequired]
51+ [JsonPropertyName("name")]
52+ public string Name { get; set; }
53+ }
54+
55+ public partial class B
56+ {
57+ [JsonRequired]
58+ [JsonPropertyName("name")]
59+ public string Name { get; set; }
60+
61+ [JsonRequired]
62+ [JsonPropertyName("out")]
63+ public C[] Out { get; set; }
64+ }
65+
66+ public partial class A
67+ {
68+ public static A FromJson(string json) => JsonSerializer.Deserialize<A>(json, QuickType.Converter.Settings);
69+ }
70+
71+ public partial class B
72+ {
73+ public static B FromJson(string json) => JsonSerializer.Deserialize<B>(json, QuickType.Converter.Settings);
74+ }
75+
76+ public partial class C
77+ {
78+ public static C FromJson(string json) => JsonSerializer.Deserialize<C>(json, QuickType.Converter.Settings);
79+ }
80+
81+ public partial class TopLevel
82+ {
83+ public static TopLevel FromJson(string json) => JsonSerializer.Deserialize<TopLevel>(json, QuickType.Converter.Settings);
84+ }
85+
86+ public static partial class Serialize
87+ {
88+ public static string ToJson(this A self) => JsonSerializer.Serialize(self, QuickType.Converter.Settings);
89+ public static string ToJson(this B self) => JsonSerializer.Serialize(self, QuickType.Converter.Settings);
90+ public static string ToJson(this C self) => JsonSerializer.Serialize(self, QuickType.Converter.Settings);
91+ public static string ToJson(this TopLevel self) => JsonSerializer.Serialize(self, QuickType.Converter.Settings);
92+ }
93+
94+ internal static partial class Converter
95+ {
96+ public static readonly JsonSerializerOptions Settings = new(JsonSerializerDefaults.General)
97+ {
98+ Converters =
99+ {
100+ new DateOnlyConverter(),
101+ new TimeOnlyConverter(),
102+ IsoDateTimeOffsetConverter.Singleton
103+ },
104+ };
105+ }
106+
107+ public class DateOnlyConverter : JsonConverter<DateOnly>
108+ {
109+ private readonly string serializationFormat;
110+ public DateOnlyConverter() : this(null) { }
111+
112+ public DateOnlyConverter(string? serializationFormat)
113+ {
114+ this.serializationFormat = serializationFormat ?? "yyyy-MM-dd";
115+ }
116+
117+ public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
118+ {
119+ var value = reader.GetString();
120+ return DateOnly.Parse(value!);
121+ }
122+
123+ public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
124+ => writer.WriteStringValue(value.ToString(serializationFormat));
125+ }
126+
127+ public class TimeOnlyConverter : JsonConverter<TimeOnly>
128+ {
129+ private readonly string serializationFormat;
130+
131+ public TimeOnlyConverter() : this(null) { }
132+
133+ public TimeOnlyConverter(string? serializationFormat)
134+ {
135+ this.serializationFormat = serializationFormat ?? "HH:mm:ss.fff";
136+ }
137+
138+ public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
139+ {
140+ var value = reader.GetString();
141+ return TimeOnly.Parse(value!);
142+ }
143+
144+ public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options)
145+ => writer.WriteStringValue(value.ToString(serializationFormat));
146+ }
147+
148+ internal class IsoDateTimeOffsetConverter : JsonConverter<DateTimeOffset>
149+ {
150+ public override bool CanConvert(Type t) => t == typeof(DateTimeOffset);
151+
152+ private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
153+
154+ private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
155+ private string? _dateTimeFormat;
156+ private CultureInfo? _culture;
157+
158+ public DateTimeStyles DateTimeStyles
159+ {
160+ get => _dateTimeStyles;
161+ set => _dateTimeStyles = value;
162+ }
163+
164+ public string? DateTimeFormat
165+ {
166+ get => _dateTimeFormat ?? string.Empty;
167+ set => _dateTimeFormat = (string.IsNullOrEmpty(value)) ? null : value;
168+ }
169+
170+ public CultureInfo Culture
171+ {
172+ get => _culture ?? CultureInfo.CurrentCulture;
173+ set => _culture = value;
174+ }
175+
176+ public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
177+ {
178+ string text;
179+
180+
181+ if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
182+ || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
183+ {
184+ value = value.ToUniversalTime();
185+ }
186+
187+ text = value.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
188+
189+ writer.WriteStringValue(text);
190+ }
191+
192+ public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
193+ {
194+ string? dateText = reader.GetString();
195+
196+ if (string.IsNullOrEmpty(dateText) == false)
197+ {
198+ if (!string.IsNullOrEmpty(_dateTimeFormat))
199+ {
200+ return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
201+ }
202+ else
203+ {
204+ return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
205+ }
206+ }
207+ else
208+ {
209+ return default(DateTimeOffset);
210+ }
211+ }
212+
213+
214+ public static readonly IsoDateTimeOffsetConverter Singleton = new IsoDateTimeOffsetConverter();
215+ }
216+}
217+#pragma warning restore CS8618
218+#pragma warning restore CS8601
219+#pragma warning restore CS8602
220+#pragma warning restore CS8603
Aschema-csharpdefault / QuickType.cs+109 −0
@@ -0,0 +1,109 @@
1+// <auto-generated />
2+//
3+// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do one of these:
4+//
5+// using QuickType;
6+//
7+// var a = A.FromJson(jsonString);
8+// var b = B.FromJson(jsonString);
9+// var c = C.FromJson(jsonString);
10+// var topLevel = TopLevel.FromJson(jsonString);
11+#nullable enable
12+#pragma warning disable CS8618
13+#pragma warning disable CS8601
14+#pragma warning disable CS8602
15+#pragma warning disable CS8603
16+#pragma warning disable CS8604
17+#pragma warning disable CS8625
18+#pragma warning disable CS8765
19+
20+namespace QuickType
21+{
22+ using System;
23+ using System.Collections.Generic;
24+
25+ using System.Globalization;
26+ using Newtonsoft.Json;
27+ using Newtonsoft.Json.Converters;
28+
29+ public partial class TopLevel
30+ {
31+ [JsonProperty("a", Required = Required.Always)]
32+ public A A { get; set; }
33+
34+ [JsonProperty("b", Required = Required.Always)]
35+ public B B { get; set; }
36+ }
37+
38+ public partial class A
39+ {
40+ [JsonProperty("in", Required = Required.Always)]
41+ public C[] In { get; set; }
42+
43+ [JsonProperty("name", Required = Required.Always)]
44+ public string Name { get; set; }
45+ }
46+
47+ public partial class C
48+ {
49+ [JsonProperty("name", Required = Required.Always)]
50+ public string Name { get; set; }
51+ }
52+
53+ public partial class B
54+ {
55+ [JsonProperty("name", Required = Required.Always)]
56+ public string Name { get; set; }
57+
58+ [JsonProperty("out", Required = Required.Always)]
59+ public C[] Out { get; set; }
60+ }
61+
62+ public partial class A
63+ {
64+ public static A FromJson(string json) => JsonConvert.DeserializeObject<A>(json, QuickType.Converter.Settings);
65+ }
66+
67+ public partial class B
68+ {
69+ public static B FromJson(string json) => JsonConvert.DeserializeObject<B>(json, QuickType.Converter.Settings);
70+ }
71+
72+ public partial class C
73+ {
74+ public static C FromJson(string json) => JsonConvert.DeserializeObject<C>(json, QuickType.Converter.Settings);
75+ }
76+
77+ public partial class TopLevel
78+ {
79+ public static TopLevel FromJson(string json) => JsonConvert.DeserializeObject<TopLevel>(json, QuickType.Converter.Settings);
80+ }
81+
82+ public static partial class Serialize
83+ {
84+ public static string ToJson(this A self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
85+ public static string ToJson(this B self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
86+ public static string ToJson(this C self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
87+ public static string ToJson(this TopLevel self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
88+ }
89+
90+ internal static partial class Converter
91+ {
92+ public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
93+ {
94+ MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
95+ DateParseHandling = DateParseHandling.None,
96+ Converters =
97+ {
98+ new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
99+ },
100+ };
101+ }
102+}
103+#pragma warning restore CS8618
104+#pragma warning restore CS8601
105+#pragma warning restore CS8602
106+#pragma warning restore CS8603
107+#pragma warning restore CS8604
108+#pragma warning restore CS8625
109+#pragma warning restore CS8765
Aschema-dartdefault / TopLevel.dart+100 −0
@@ -0,0 +1,100 @@
1+// To parse this JSON data, do
2+//
3+// final a = aFromJson(jsonString);
4+// final b = bFromJson(jsonString);
5+// final c = cFromJson(jsonString);
6+// final topLevel = topLevelFromJson(jsonString);
7+
8+import 'dart:convert';
9+
10+A aFromJson(String str) => A.fromJson(json.decode(str));
11+
12+String aToJson(A data) => json.encode(data.toJson());
13+
14+B bFromJson(String str) => B.fromJson(json.decode(str));
15+
16+String bToJson(B data) => json.encode(data.toJson());
17+
18+C cFromJson(String str) => C.fromJson(json.decode(str));
19+
20+String cToJson(C data) => json.encode(data.toJson());
21+
22+TopLevel topLevelFromJson(String str) => TopLevel.fromJson(json.decode(str));
23+
24+String topLevelToJson(TopLevel data) => json.encode(data.toJson());
25+
26+class TopLevel {
27+ final A a;
28+ final B b;
29+
30+ TopLevel({
31+ required this.a,
32+ required this.b,
33+ });
34+
35+ factory TopLevel.fromJson(Map<String, dynamic> json) => TopLevel(
36+ a: A.fromJson(json["a"]),
37+ b: B.fromJson(json["b"]),
38+ );
39+
40+ Map<String, dynamic> toJson() => {
41+ "a": a.toJson(),
42+ "b": b.toJson(),
43+ };
44+}
45+
46+class A {
47+ final List<C> aIn;
48+ final String name;
49+
50+ A({
51+ required this.aIn,
52+ required this.name,
53+ });
54+
55+ factory A.fromJson(Map<String, dynamic> json) => A(
56+ aIn: List<C>.from(json["in"].map((x) => C.fromJson(x))),
57+ name: json["name"],
58+ );
59+
60+ Map<String, dynamic> toJson() => {
61+ "in": List<dynamic>.from(aIn.map((x) => x.toJson())),
62+ "name": name,
63+ };
64+}
65+
66+class C {
67+ final String name;
68+
69+ C({
70+ required this.name,
71+ });
72+
73+ factory C.fromJson(Map<String, dynamic> json) => C(
74+ name: json["name"],
75+ );
76+
77+ Map<String, dynamic> toJson() => {
78+ "name": name,
79+ };
80+}
81+
82+class B {
83+ final String name;
84+ final List<C> out;
85+
86+ B({
87+ required this.name,
88+ required this.out,
89+ });
90+
91+ factory B.fromJson(Map<String, dynamic> json) => B(
92+ name: json["name"],
93+ out: List<C>.from(json["out"].map((x) => C.fromJson(x))),
94+ );
95+
96+ Map<String, dynamic> toJson() => {
97+ "name": name,
98+ "out": List<dynamic>.from(out.map((x) => x.toJson())),
99+ };
100+}
Aschema-flowdefault / TopLevel.js+252 −0
@@ -0,0 +1,252 @@
1+// @flow
2+
3+// To parse this data:
4+//
5+// const Convert = require("./TopLevel");
6+//
7+// const a = Convert.toA(json);
8+// const b = Convert.toB(json);
9+// const c = Convert.toC(json);
10+// const topLevel = Convert.toTopLevel(json);
11+//
12+// These functions will throw an error if the JSON doesn't
13+// match the expected interface, even if the JSON is valid.
14+
15+export type TopLevel = {
16+ a: A;
17+ b: B;
18+ [property: string]: mixed;
19+};
20+
21+export type A = {
22+ in: C[];
23+ name: string;
24+ [property: string]: mixed;
25+};
26+
27+export type C = {
28+ name: string;
29+ [property: string]: mixed;
30+};
31+
32+export type B = {
33+ name: string;
34+ out: C[];
35+ [property: string]: mixed;
36+};
37+
38+// Converts JSON strings to/from your types
39+// and asserts the results of JSON.parse at runtime
40+function toA(json: string): A {
41+ return cast(JSON.parse(json), r("A"));
42+}
43+
44+function aToJson(value: A): string {
45+ return JSON.stringify(uncast(value, r("A")), null, 2);
46+}
47+
48+function toB(json: string): B {
49+ return cast(JSON.parse(json), r("B"));
50+}
51+
52+function bToJson(value: B): string {
53+ return JSON.stringify(uncast(value, r("B")), null, 2);
54+}
55+
56+function toC(json: string): C {
57+ return cast(JSON.parse(json), r("C"));
58+}
59+
60+function cToJson(value: C): string {
61+ return JSON.stringify(uncast(value, r("C")), null, 2);
62+}
63+
64+function toTopLevel(json: string): TopLevel {
65+ return cast(JSON.parse(json), r("TopLevel"));
66+}
67+
68+function topLevelToJson(value: TopLevel): string {
69+ return JSON.stringify(uncast(value, r("TopLevel")), null, 2);
70+}
71+
72+function invalidValue(typ: any, val: any, key: any, parent: any = '') {
73+ const prettyTyp = prettyTypeName(typ);
74+ const parentText = parent ? ` on ${parent}` : '';
75+ const keyText = key ? ` for key "${key}"` : '';
76+ throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`);
77+}
78+
79+function prettyTypeName(typ: any): string {
80+ if (Array.isArray(typ)) {
81+ if (typ.length === 2 && typ[0] === undefined) {
82+ return `an optional ${prettyTypeName(typ[1])}`;
83+ } else {
84+ return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`;
85+ }
86+ } else if (typeof typ === "object" && typ.literal !== undefined) {
87+ return typ.literal;
88+ } else {
89+ return typeof typ;
90+ }
91+}
92+
93+function jsonToJSProps(typ: any): any {
94+ if (typ.jsonToJS === undefined) {
95+ const map: any = {};
96+ typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ });
97+ typ.jsonToJS = map;
98+ }
99+ return typ.jsonToJS;
100+}
101+
102+function jsToJSONProps(typ: any): any {
103+ if (typ.jsToJSON === undefined) {
104+ const map: any = {};
105+ typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ });
106+ typ.jsToJSON = map;
107+ }
108+ return typ.jsToJSON;
109+}
110+
111+function transform(val: any, typ: any, getProps: any, key: any = '', parent: any = ''): any {
112+ function transformPrimitive(typ: string, val: any): any {
113+ if (typeof typ === typeof val) return val;
114+ return invalidValue(typ, val, key, parent);
115+ }
116+
117+ function transformUnion(typs: any[], val: any): any {
118+ // val must validate against one typ in typs
119+ const l = typs.length;
120+ for (let i = 0; i < l; i++) {
121+ const typ = typs[i];
122+ try {
123+ return transform(val, typ, getProps);
124+ } catch (_) {}
125+ }
126+ return invalidValue(typs, val, key, parent);
127+ }
128+
129+ function transformEnum(cases: string[], val: any): any {
130+ if (cases.indexOf(val) !== -1) return val;
131+ return invalidValue(cases.map(a => { return l(a); }), val, key, parent);
132+ }
133+
134+ function transformArray(typ: any, val: any): any {
135+ // val must be an array with no invalid elements
136+ if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent);
137+ return val.map(el => transform(el, typ, getProps));
138+ }
139+
140+ function transformDate(val: any): any {
141+ if (val === null) {
142+ return null;
143+ }
144+ const d = new Date(val);
145+ if (isNaN(d.valueOf())) {
146+ return invalidValue(l("Date"), val, key, parent);
147+ }
148+ return d;
149+ }
150+
151+ function transformObject(props: { [k: string]: any }, additional: any, val: any): any {
152+ if (val === null || typeof val !== "object" || Array.isArray(val)) {
153+ return invalidValue(l(ref || "object"), val, key, parent);
154+ }
155+ const result: any = {};
156+ Object.getOwnPropertyNames(props).forEach(key => {
157+ const prop = props[key];
158+ const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined;
159+ result[prop.key] = transform(v, prop.typ, getProps, key, ref);
160+ });
161+ Object.getOwnPropertyNames(val).forEach(key => {
162+ if (!Object.prototype.hasOwnProperty.call(props, key)) {
163+ result[key] = transform(val[key], additional, getProps, key, ref);
164+ }
165+ });
166+ return result;
167+ }
168+
169+ if (typ === "any") return val;
170+ if (typ === null) {
171+ if (val === null) return val;
172+ return invalidValue(typ, val, key, parent);
173+ }
174+ if (typ === false) return invalidValue(typ, val, key, parent);
175+ let ref: any = undefined;
176+ while (typeof typ === "object" && typ.ref !== undefined) {
177+ ref = typ.ref;
178+ typ = typeMap[typ.ref];
179+ }
180+ if (Array.isArray(typ)) return transformEnum(typ, val);
181+ if (typeof typ === "object") {
182+ return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val)
183+ : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val)
184+ : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val)
185+ : invalidValue(typ, val, key, parent);
186+ }
187+ // Numbers can be parsed by Date but shouldn't be.
188+ if (typ === Date && typeof val !== "number") return transformDate(val);
189+ return transformPrimitive(typ, val);
190+}
191+
192+function cast<T>(val: any, typ: any): T {
193+ return transform(val, typ, jsonToJSProps);
194+}
195+
196+function uncast<T>(val: T, typ: any): any {
197+ return transform(val, typ, jsToJSONProps);
198+}
199+
200+function l(typ: any) {
201+ return { literal: typ };
202+}
203+
204+function a(typ: any) {
205+ return { arrayItems: typ };
206+}
207+
208+function u(...typs: any[]) {
209+ return { unionMembers: typs };
210+}
211+
212+function o(props: any[], additional: any) {
213+ return { props, additional };
214+}
215+
216+function m(additional: any) {
217+ const props: any[] = [];
218+ return { props, additional };
219+}
220+
221+function r(name: string) {
222+ return { ref: name };
223+}
224+
225+const typeMap: any = {
226+ "TopLevel": o([
227+ { json: "a", js: "a", typ: r("A") },
228+ { json: "b", js: "b", typ: r("B") },
229+ ], "any"),
230+ "A": o([
231+ { json: "in", js: "in", typ: a(r("C")) },
232+ { json: "name", js: "name", typ: "" },
233+ ], "any"),
234+ "C": o([
235+ { json: "name", js: "name", typ: "" },
236+ ], "any"),
237+ "B": o([
238+ { json: "name", js: "name", typ: "" },
239+ { json: "out", js: "out", typ: a(r("C")) },
240+ ], "any"),
241+};
242+
243+module.exports = {
244+ "aToJson": aToJson,
245+ "toA": toA,
246+ "bToJson": bToJson,
247+ "toB": toB,
248+ "cToJson": cToJson,
249+ "toC": toC,
250+ "topLevelToJson": topLevelToJson,
251+ "toTopLevel": toTopLevel,
252+};
Aschema-golangdefault / quicktype.go+77 −0
@@ -0,0 +1,77 @@
1+// Code generated from JSON Schema using quicktype. DO NOT EDIT.
2+// To parse and unparse this JSON data, add this code to your project and do:
3+//
4+// a, err := UnmarshalA(bytes)
5+// bytes, err = a.Marshal()
6+//
7+// b, err := UnmarshalB(bytes)
8+// bytes, err = b.Marshal()
9+//
10+// c, err := UnmarshalC(bytes)
11+// bytes, err = c.Marshal()
12+//
13+// topLevel, err := UnmarshalTopLevel(bytes)
14+// bytes, err = topLevel.Marshal()
15+
16+package main
17+
18+import "encoding/json"
19+
20+func UnmarshalA(data []byte) (A, error) {
21+ var r A
22+ err := json.Unmarshal(data, &r)
23+ return r, err
24+}
25+
26+func (r *A) Marshal() ([]byte, error) {
27+ return json.Marshal(r)
28+}
29+
30+func UnmarshalB(data []byte) (B, error) {
31+ var r B
32+ err := json.Unmarshal(data, &r)
33+ return r, err
34+}
35+
36+func (r *B) Marshal() ([]byte, error) {
37+ return json.Marshal(r)
38+}
39+
40+func UnmarshalC(data []byte) (C, error) {
41+ var r C
42+ err := json.Unmarshal(data, &r)
43+ return r, err
44+}
45+
46+func (r *C) Marshal() ([]byte, error) {
47+ return json.Marshal(r)
48+}
49+
50+func UnmarshalTopLevel(data []byte) (TopLevel, error) {
51+ var r TopLevel
52+ err := json.Unmarshal(data, &r)
53+ return r, err
54+}
55+
56+func (r *TopLevel) Marshal() ([]byte, error) {
57+ return json.Marshal(r)
58+}
59+
60+type TopLevel struct {
61+ A A `json:"a"`
62+ B B `json:"b"`
63+}
64+
65+type A struct {
66+ In []C `json:"in"`
67+ Name string `json:"name"`
68+}
69+
70+type C struct {
71+ Name string `json:"name"`
72+}
73+
74+type B struct {
75+ Name string `json:"name"`
76+ Out []C `json:"out"`
77+}
Aschema-javascriptdefault / TopLevel.js+227 −0
@@ -0,0 +1,227 @@
1+// To parse this data:
2+//
3+// const Convert = require("./TopLevel");
4+//
5+// const a = Convert.toA(json);
6+// const b = Convert.toB(json);
7+// const c = Convert.toC(json);
8+// const topLevel = Convert.toTopLevel(json);
9+//
10+// These functions will throw an error if the JSON doesn't
11+// match the expected interface, even if the JSON is valid.
12+
13+// Converts JSON strings to/from your types
14+// and asserts the results of JSON.parse at runtime
15+function toA(json) {
16+ return cast(JSON.parse(json), r("A"));
17+}
18+
19+function aToJson(value) {
20+ return JSON.stringify(uncast(value, r("A")), null, 2);
21+}
22+
23+function toB(json) {
24+ return cast(JSON.parse(json), r("B"));
25+}
26+
27+function bToJson(value) {
28+ return JSON.stringify(uncast(value, r("B")), null, 2);
29+}
30+
31+function toC(json) {
32+ return cast(JSON.parse(json), r("C"));
33+}
34+
35+function cToJson(value) {
36+ return JSON.stringify(uncast(value, r("C")), null, 2);
37+}
38+
39+function toTopLevel(json) {
40+ return cast(JSON.parse(json), r("TopLevel"));
41+}
42+
43+function topLevelToJson(value) {
44+ return JSON.stringify(uncast(value, r("TopLevel")), null, 2);
45+}
46+
47+function invalidValue(typ, val, key, parent = '') {
48+ const prettyTyp = prettyTypeName(typ);
49+ const parentText = parent ? ` on ${parent}` : '';
50+ const keyText = key ? ` for key "${key}"` : '';
51+ throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`);
52+}
53+
54+function prettyTypeName(typ) {
55+ if (Array.isArray(typ)) {
56+ if (typ.length === 2 && typ[0] === undefined) {
57+ return `an optional ${prettyTypeName(typ[1])}`;
58+ } else {
59+ return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`;
60+ }
61+ } else if (typeof typ === "object" && typ.literal !== undefined) {
62+ return typ.literal;
63+ } else {
64+ return typeof typ;
65+ }
66+}
67+
68+function jsonToJSProps(typ) {
69+ if (typ.jsonToJS === undefined) {
70+ const map = {};
71+ typ.props.forEach((p) => map[p.json] = { key: p.js, typ: p.typ });
72+ typ.jsonToJS = map;
73+ }
74+ return typ.jsonToJS;
75+}
76+
77+function jsToJSONProps(typ) {
78+ if (typ.jsToJSON === undefined) {
79+ const map = {};
80+ typ.props.forEach((p) => map[p.js] = { key: p.json, typ: p.typ });
81+ typ.jsToJSON = map;
82+ }
83+ return typ.jsToJSON;
84+}
85+
86+function transform(val, typ, getProps, key = '', parent = '') {
87+ function transformPrimitive(typ, val) {
88+ if (typeof typ === typeof val) return val;
89+ return invalidValue(typ, val, key, parent);
90+ }
91+
92+ function transformUnion(typs, val) {
93+ // val must validate against one typ in typs
94+ const l = typs.length;
95+ for (let i = 0; i < l; i++) {
96+ const typ = typs[i];
97+ try {
98+ return transform(val, typ, getProps);
99+ } catch (_) {}
100+ }
101+ return invalidValue(typs, val, key, parent);
102+ }
103+
104+ function transformEnum(cases, val) {
105+ if (cases.indexOf(val) !== -1) return val;
106+ return invalidValue(cases.map(a => { return l(a); }), val, key, parent);
107+ }
108+
109+ function transformArray(typ, val) {
110+ // val must be an array with no invalid elements
111+ if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent);
112+ return val.map(el => transform(el, typ, getProps));
113+ }
114+
115+ function transformDate(val) {
116+ if (val === null) {
117+ return null;
118+ }
119+ const d = new Date(val);
120+ if (isNaN(d.valueOf())) {
121+ return invalidValue(l("Date"), val, key, parent);
122+ }
123+ return d;
124+ }
125+
126+ function transformObject(props, additional, val) {
127+ if (val === null || typeof val !== "object" || Array.isArray(val)) {
128+ return invalidValue(l(ref || "object"), val, key, parent);
129+ }
130+ const result = {};
131+ Object.getOwnPropertyNames(props).forEach(key => {
132+ const prop = props[key];
133+ const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined;
134+ result[prop.key] = transform(v, prop.typ, getProps, key, ref);
135+ });
136+ Object.getOwnPropertyNames(val).forEach(key => {
137+ if (!Object.prototype.hasOwnProperty.call(props, key)) {
138+ result[key] = transform(val[key], additional, getProps, key, ref);
139+ }
140+ });
141+ return result;
142+ }
143+
144+ if (typ === "any") return val;
145+ if (typ === null) {
146+ if (val === null) return val;
147+ return invalidValue(typ, val, key, parent);
148+ }
149+ if (typ === false) return invalidValue(typ, val, key, parent);
150+ let ref = undefined;
151+ while (typeof typ === "object" && typ.ref !== undefined) {
152+ ref = typ.ref;
153+ typ = typeMap[typ.ref];
154+ }
155+ if (Array.isArray(typ)) return transformEnum(typ, val);
156+ if (typeof typ === "object") {
157+ return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val)
158+ : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val)
159+ : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val)
160+ : invalidValue(typ, val, key, parent);
161+ }
162+ // Numbers can be parsed by Date but shouldn't be.
163+ if (typ === Date && typeof val !== "number") return transformDate(val);
164+ return transformPrimitive(typ, val);
165+}
166+
167+function cast(val, typ) {
168+ return transform(val, typ, jsonToJSProps);
169+}
170+
171+function uncast(val, typ) {
172+ return transform(val, typ, jsToJSONProps);
173+}
174+
175+function l(typ) {
176+ return { literal: typ };
177+}
178+
179+function a(typ) {
180+ return { arrayItems: typ };
181+}
182+
183+function u(...typs) {
184+ return { unionMembers: typs };
185+}
186+
187+function o(props, additional) {
188+ return { props, additional };
189+}
190+
191+function m(additional) {
192+ const props = [];
193+ return { props, additional };
194+}
195+
196+function r(name) {
197+ return { ref: name };
198+}
199+
200+const typeMap = {
201+ "TopLevel": o([
202+ { json: "a", js: "a", typ: r("A") },
203+ { json: "b", js: "b", typ: r("B") },
204+ ], "any"),
205+ "A": o([
206+ { json: "in", js: "in", typ: a(r("C")) },
207+ { json: "name", js: "name", typ: "" },
208+ ], "any"),
209+ "C": o([
210+ { json: "name", js: "name", typ: "" },
211+ ], "any"),
212+ "B": o([
213+ { json: "name", js: "name", typ: "" },
214+ { json: "out", js: "out", typ: a(r("C")) },
215+ ], "any"),
216+};
217+
218+module.exports = {
219+ "aToJson": aToJson,
220+ "toA": toA,
221+ "bToJson": bToJson,
222+ "toB": toB,
223+ "cToJson": cToJson,
224+ "toC": toC,
225+ "topLevelToJson": topLevelToJson,
226+ "toTopLevel": toTopLevel,
227+};
Aschema-kotlin-jacksondefault / TopLevel.kt+75 −0
@@ -0,0 +1,75 @@
1+// To parse the JSON, install jackson-module-kotlin and do:
2+//
3+// val a = A.fromJson(jsonString)
4+// val b = B.fromJson(jsonString)
5+// val c = C.fromJson(jsonString)
6+// val topLevel = TopLevel.fromJson(jsonString)
7+
8+package quicktype
9+
10+import com.fasterxml.jackson.annotation.*
11+import com.fasterxml.jackson.core.*
12+import com.fasterxml.jackson.databind.*
13+import com.fasterxml.jackson.databind.deser.std.StdDeserializer
14+import com.fasterxml.jackson.databind.module.SimpleModule
15+import com.fasterxml.jackson.databind.node.*
16+import com.fasterxml.jackson.databind.ser.std.StdSerializer
17+import com.fasterxml.jackson.module.kotlin.*
18+
19+val mapper = jacksonObjectMapper().apply {
20+ propertyNamingStrategy = PropertyNamingStrategy.LOWER_CAMEL_CASE
21+ setSerializationInclusion(JsonInclude.Include.NON_NULL)
22+}
23+
24+data class TopLevel (
25+ @get:JsonProperty(required=true)@field:JsonProperty(required=true)
26+ val a: A,
27+
28+ @get:JsonProperty(required=true)@field:JsonProperty(required=true)
29+ val b: B
30+) {
31+ fun toJson() = mapper.writeValueAsString(this)
32+
33+ companion object {
34+ fun fromJson(json: String) = mapper.readValue<TopLevel>(json)
35+ }
36+}
37+
38+data class A (
39+ @get:JsonProperty("in", required=true)@field:JsonProperty("in", required=true)
40+ val aIn: List<C>,
41+
42+ @get:JsonProperty(required=true)@field:JsonProperty(required=true)
43+ val name: String
44+) {
45+ fun toJson() = mapper.writeValueAsString(this)
46+
47+ companion object {
48+ fun fromJson(json: String) = mapper.readValue<A>(json)
49+ }
50+}
51+
52+data class C (
53+ @get:JsonProperty(required=true)@field:JsonProperty(required=true)
54+ val name: String
55+) {
56+ fun toJson() = mapper.writeValueAsString(this)
57+
58+ companion object {
59+ fun fromJson(json: String) = mapper.readValue<C>(json)
60+ }
61+}
62+
63+data class B (
64+ @get:JsonProperty(required=true)@field:JsonProperty(required=true)
65+ val name: String,
66+
67+ @get:JsonProperty(required=true)@field:JsonProperty(required=true)
68+ val out: List<C>
69+) {
70+ fun toJson() = mapper.writeValueAsString(this)
71+
72+ companion object {
73+ fun fromJson(json: String) = mapper.readValue<B>(json)
74+ }
75+}
Aschema-kotlindefault / TopLevel.kt+57 −0
@@ -0,0 +1,57 @@
1+// To parse the JSON, install Klaxon and do:
2+//
3+// val a = A.fromJson(jsonString)
4+// val b = B.fromJson(jsonString)
5+// val c = C.fromJson(jsonString)
6+// val topLevel = TopLevel.fromJson(jsonString)
7+
8+package quicktype
9+
10+import com.beust.klaxon.*
11+
12+private val klaxon = Klaxon()
13+
14+data class TopLevel (
15+ val a: A,
16+ val b: B
17+) {
18+ public fun toJson() = klaxon.toJsonString(this)
19+
20+ companion object {
21+ public fun fromJson(json: String) = klaxon.parse<TopLevel>(json)
22+ }
23+}
24+
25+data class A (
26+ @Json(name = "in")
27+ val aIn: List<C>,
28+
29+ val name: String
30+) {
31+ public fun toJson() = klaxon.toJsonString(this)
32+
33+ companion object {
34+ public fun fromJson(json: String) = klaxon.parse<A>(json)
35+ }
36+}
37+
38+data class C (
39+ val name: String
40+) {
41+ public fun toJson() = klaxon.toJsonString(this)
42+
43+ companion object {
44+ public fun fromJson(json: String) = klaxon.parse<C>(json)
45+ }
46+}
47+
48+data class B (
49+ val name: String,
50+ val out: List<C>
51+) {
52+ public fun toJson() = klaxon.toJsonString(this)
53+
54+ companion object {
55+ public fun fromJson(json: String) = klaxon.parse<B>(json)
56+ }
57+}
Aschema-kotlinxdefault / TopLevel.kt+39 −0
@@ -0,0 +1,39 @@
1+// To parse the JSON, install kotlin's serialization plugin and do:
2+//
3+// val json = Json { allowStructuredMapKeys = true }
4+// val a = json.parse(A.serializer(), jsonString)
5+// val b = json.parse(B.serializer(), jsonString)
6+// val c = json.parse(C.serializer(), jsonString)
7+// val topLevel = json.parse(TopLevel.serializer(), jsonString)
8+
9+package quicktype
10+
11+import kotlinx.serialization.*
12+import kotlinx.serialization.json.*
13+import kotlinx.serialization.descriptors.*
14+import kotlinx.serialization.encoding.*
15+
16+@Serializable
17+data class TopLevel (
18+ val a: A,
19+ val b: B
20+)
21+
22+@Serializable
23+data class A (
24+ @SerialName("in")
25+ val aIn: List<C>,
26+
27+ val name: String
28+)
29+
30+@Serializable
31+data class C (
32+ val name: String
33+)
34+
35+@Serializable
36+data class B (
37+ val name: String,
38+ val out: List<C>
39+)
Aschema-phpdefault / TopLevel.php+582 −0
@@ -0,0 +1,582 @@
1+<?php
2+declare(strict_types=1);
3+
4+// This is an autogenerated file:TopLevel
5+
6+class TopLevel {
7+ private A $a; // json:a Required
8+ private B $b; // json:b Required
9+
10+ /**
11+ * @param A $a
12+ * @param B $b
13+ */
14+ public function __construct(A $a, B $b) {
15+ $this->a = $a;
16+ $this->b = $b;
17+ }
18+
19+ /**
20+ * @param stdClass $value
21+ * @throws Exception
22+ * @return A
23+ */
24+ public static function fromA(stdClass $value): A {
25+ return A::from($value); /*class*/
26+ }
27+
28+ /**
29+ * @throws Exception
30+ * @return stdClass
31+ */
32+ public function toA(): stdClass {
33+ if (TopLevel::validateA($this->a)) {
34+ return $this->a->to(); /*class*/
35+ }
36+ throw new Exception('never get to this TopLevel::a');
37+ }
38+
39+ /**
40+ * @param A
41+ * @return bool
42+ * @throws Exception
43+ */
44+ public static function validateA(A $value): bool {
45+ $value->validate();
46+ return true;
47+ }
48+
49+ /**
50+ * @throws Exception
51+ * @return A
52+ */
53+ public function getA(): A {
54+ if (TopLevel::validateA($this->a)) {
55+ return $this->a;
56+ }
57+ throw new Exception('never get to getA TopLevel::a');
58+ }
59+
60+ /**
61+ * @return A
62+ */
63+ public static function sampleA(): A {
64+ return A::sample(); /*31:a*/
65+ }
66+
67+ /**
68+ * @param stdClass $value
69+ * @throws Exception
70+ * @return B
71+ */
72+ public static function fromB(stdClass $value): B {
73+ return B::from($value); /*class*/
74+ }
75+
76+ /**
77+ * @throws Exception
78+ * @return stdClass
79+ */
80+ public function toB(): stdClass {
81+ if (TopLevel::validateB($this->b)) {
82+ return $this->b->to(); /*class*/
83+ }
84+ throw new Exception('never get to this TopLevel::b');
85+ }
86+
87+ /**
88+ * @param B
89+ * @return bool
90+ * @throws Exception
91+ */
92+ public static function validateB(B $value): bool {
93+ $value->validate();
94+ return true;
95+ }
96+
97+ /**
98+ * @throws Exception
99+ * @return B
100+ */
101+ public function getB(): B {
102+ if (TopLevel::validateB($this->b)) {
103+ return $this->b;
104+ }
105+ throw new Exception('never get to getB TopLevel::b');
106+ }
107+
108+ /**
109+ * @return B
110+ */
111+ public static function sampleB(): B {
112+ return B::sample(); /*32:b*/
113+ }
114+
115+ /**
116+ * @throws Exception
117+ * @return bool
118+ */
119+ public function validate(): bool {
120+ return TopLevel::validateA($this->a)
121+ || TopLevel::validateB($this->b);
122+ }
123+
124+ /**
125+ * @return stdClass
126+ * @throws Exception
127+ */
128+ public function to(): stdClass {
129+ $out = new stdClass();
130+ $out->{'a'} = $this->toA();
131+ $out->{'b'} = $this->toB();
132+ return $out;
133+ }
134+
135+ /**
136+ * @param stdClass $obj
137+ * @return TopLevel
138+ * @throws Exception
139+ */
140+ public static function from(stdClass $obj): TopLevel {
141+ return new TopLevel(
142+ TopLevel::fromA($obj->{'a'})
143+ ,TopLevel::fromB($obj->{'b'})
144+ );
145+ }
146+
147+ /**
148+ * @return TopLevel
149+ */
150+ public static function sample(): TopLevel {
151+ return new TopLevel(
152+ TopLevel::sampleA()
153+ ,TopLevel::sampleB()
154+ );
155+ }
156+}
157+
158+// This is an autogenerated file:A
159+
160+class A {
161+ private array $in; // json:in Required
162+ private string $name; // json:name Required
163+
164+ /**
165+ * @param array $in
166+ * @param string $name
167+ */
168+ public function __construct(array $in, string $name) {
169+ $this->in = $in;
170+ $this->name = $name;
171+ }
172+
173+ /**
174+ * @param array $value
175+ * @throws Exception
176+ * @return array
177+ */
178+ public static function fromIn(array $value): array {
179+ return array_map(function ($value) {
180+ return C::from($value); /*class*/
181+ }, $value);
182+ }
183+
184+ /**
185+ * @throws Exception
186+ * @return array
187+ */
188+ public function toIn(): array {
189+ if (A::validateIn($this->in)) {
190+ return array_map(function ($value) {
191+ return $value->to(); /*class*/
192+ }, $this->in);
193+ }
194+ throw new Exception('never get to this A::in');
195+ }
196+
197+ /**
198+ * @param array
199+ * @return bool
200+ * @throws Exception
201+ */
202+ public static function validateIn(array $value): bool {
203+ if (!is_array($value)) {
204+ throw new Exception("Attribute Error:A::in");
205+ }
206+ array_walk($value, function($value_v) {
207+ $value_v->validate();
208+ });
209+ return true;
210+ }
211+
212+ /**
213+ * @throws Exception
214+ * @return array
215+ */
216+ public function getIn(): array {
217+ if (A::validateIn($this->in)) {
218+ return $this->in;
219+ }
220+ throw new Exception('never get to getIn A::in');
221+ }
222+
223+ /**
224+ * @return array
225+ */
226+ public static function sampleIn(): array {
227+ return array(
228+ C::sample() /*31:*/
229+ ); /* 31:in*/
230+ }
231+
232+ /**
233+ * @param string $value
234+ * @throws Exception
235+ * @return string
236+ */
237+ public static function fromName(string $value): string {
238+ return $value; /*string*/
239+ }
240+
241+ /**
242+ * @throws Exception
243+ * @return string
244+ */
245+ public function toName(): string {
246+ if (A::validateName($this->name)) {
247+ return $this->name; /*string*/
248+ }
249+ throw new Exception('never get to this A::name');
250+ }
251+
252+ /**
253+ * @param string
254+ * @return bool
255+ * @throws Exception
256+ */
257+ public static function validateName(string $value): bool {
258+ return true;
259+ }
260+
261+ /**
262+ * @throws Exception
263+ * @return string
264+ */
265+ public function getName(): string {
266+ if (A::validateName($this->name)) {
267+ return $this->name;
268+ }
269+ throw new Exception('never get to getName A::name');
270+ }
271+
272+ /**
273+ * @return string
274+ */
275+ public static function sampleName(): string {
276+ return 'A::name::32'; /*32:name*/
277+ }
278+
279+ /**
280+ * @throws Exception
281+ * @return bool
282+ */
283+ public function validate(): bool {
284+ return A::validateIn($this->in)
285+ || A::validateName($this->name);
286+ }
287+
288+ /**
289+ * @return stdClass
290+ * @throws Exception
291+ */
292+ public function to(): stdClass {
293+ $out = new stdClass();
294+ $out->{'in'} = $this->toIn();
295+ $out->{'name'} = $this->toName();
296+ return $out;
297+ }
298+
299+ /**
300+ * @param stdClass $obj
301+ * @return A
302+ * @throws Exception
303+ */
304+ public static function from(stdClass $obj): A {
305+ return new A(
306+ A::fromIn($obj->{'in'})
307+ ,A::fromName($obj->{'name'})
308+ );
309+ }
310+
311+ /**
312+ * @return A
313+ */
314+ public static function sample(): A {
315+ return new A(
316+ A::sampleIn()
317+ ,A::sampleName()
318+ );
319+ }
320+}
321+
322+// This is an autogenerated file:C
323+
324+class C {
325+ private string $name; // json:name Required
326+
327+ /**
328+ * @param string $name
329+ */
330+ public function __construct(string $name) {
331+ $this->name = $name;
332+ }
333+
334+ /**
335+ * @param string $value
336+ * @throws Exception
337+ * @return string
338+ */
339+ public static function fromName(string $value): string {
340+ return $value; /*string*/
341+ }
342+
343+ /**
344+ * @throws Exception
345+ * @return string
346+ */
347+ public function toName(): string {
348+ if (C::validateName($this->name)) {
349+ return $this->name; /*string*/
350+ }
351+ throw new Exception('never get to this C::name');
352+ }
353+
354+ /**
355+ * @param string
356+ * @return bool
357+ * @throws Exception
358+ */
359+ public static function validateName(string $value): bool {
360+ return true;
361+ }
362+
363+ /**
364+ * @throws Exception
365+ * @return string
366+ */
367+ public function getName(): string {
368+ if (C::validateName($this->name)) {
369+ return $this->name;
370+ }
371+ throw new Exception('never get to getName C::name');
372+ }
373+
374+ /**
375+ * @return string
376+ */
377+ public static function sampleName(): string {
378+ return 'C::name::31'; /*31:name*/
379+ }
380+
381+ /**
382+ * @throws Exception
383+ * @return bool
384+ */
385+ public function validate(): bool {
386+ return C::validateName($this->name);
387+ }
388+
389+ /**
390+ * @return stdClass
391+ * @throws Exception
392+ */
393+ public function to(): stdClass {
394+ $out = new stdClass();
395+ $out->{'name'} = $this->toName();
396+ return $out;
397+ }
398+
399+ /**
400+ * @param stdClass $obj
401+ * @return C
402+ * @throws Exception
403+ */
404+ public static function from(stdClass $obj): C {
405+ return new C(
406+ C::fromName($obj->{'name'})
407+ );
408+ }
409+
410+ /**
411+ * @return C
412+ */
413+ public static function sample(): C {
414+ return new C(
415+ C::sampleName()
416+ );
417+ }
418+}
419+
420+// This is an autogenerated file:B
421+
422+class B {
423+ private string $name; // json:name Required
424+ private array $out; // json:out Required
425+
426+ /**
427+ * @param string $name
428+ * @param array $out
429+ */
430+ public function __construct(string $name, array $out) {
431+ $this->name = $name;
432+ $this->out = $out;
433+ }
434+
435+ /**
436+ * @param string $value
437+ * @throws Exception
438+ * @return string
439+ */
440+ public static function fromName(string $value): string {
441+ return $value; /*string*/
442+ }
443+
444+ /**
445+ * @throws Exception
446+ * @return string
447+ */
448+ public function toName(): string {
449+ if (B::validateName($this->name)) {
450+ return $this->name; /*string*/
451+ }
452+ throw new Exception('never get to this B::name');
453+ }
454+
455+ /**
456+ * @param string
457+ * @return bool
458+ * @throws Exception
459+ */
460+ public static function validateName(string $value): bool {
461+ return true;
462+ }
463+
464+ /**
465+ * @throws Exception
466+ * @return string
467+ */
468+ public function getName(): string {
469+ if (B::validateName($this->name)) {
470+ return $this->name;
471+ }
472+ throw new Exception('never get to getName B::name');
473+ }
474+
475+ /**
476+ * @return string
477+ */
478+ public static function sampleName(): string {
479+ return 'B::name::31'; /*31:name*/
480+ }
481+
482+ /**
483+ * @param array $value
484+ * @throws Exception
485+ * @return array
486+ */
487+ public static function fromOut(array $value): array {
488+ return array_map(function ($value) {
489+ return C::from($value); /*class*/
490+ }, $value);
491+ }
492+
493+ /**
494+ * @throws Exception
495+ * @return array
496+ */
497+ public function toOut(): array {
498+ if (B::validateOut($this->out)) {
499+ return array_map(function ($value) {
500+ return $value->to(); /*class*/
501+ }, $this->out);
502+ }
503+ throw new Exception('never get to this B::out');
504+ }
505+
506+ /**
507+ * @param array
508+ * @return bool
509+ * @throws Exception
510+ */
511+ public static function validateOut(array $value): bool {
512+ if (!is_array($value)) {
513+ throw new Exception("Attribute Error:B::out");
514+ }
515+ array_walk($value, function($value_v) {
516+ $value_v->validate();
517+ });
518+ return true;
519+ }
520+
521+ /**
522+ * @throws Exception
523+ * @return array
524+ */
525+ public function getOut(): array {
526+ if (B::validateOut($this->out)) {
527+ return $this->out;
528+ }
529+ throw new Exception('never get to getOut B::out');
530+ }
531+
532+ /**
533+ * @return array
534+ */
535+ public static function sampleOut(): array {
536+ return array(
537+ C::sample() /*32:*/
538+ ); /* 32:out*/
539+ }
540+
541+ /**
542+ * @throws Exception
543+ * @return bool
544+ */
545+ public function validate(): bool {
546+ return B::validateName($this->name)
547+ || B::validateOut($this->out);
548+ }
549+
550+ /**
551+ * @return stdClass
552+ * @throws Exception
553+ */
554+ public function to(): stdClass {
555+ $out = new stdClass();
556+ $out->{'name'} = $this->toName();
557+ $out->{'out'} = $this->toOut();
558+ return $out;
559+ }
560+
561+ /**
562+ * @param stdClass $obj
563+ * @return B
564+ * @throws Exception
565+ */
566+ public static function from(stdClass $obj): B {
567+ return new B(
568+ B::fromName($obj->{'name'})
569+ ,B::fromOut($obj->{'out'})
570+ );
571+ }
572+
573+ /**
574+ * @return B
575+ */
576+ public static function sample(): B {
577+ return new B(
578+ B::sampleName()
579+ ,B::sampleOut()
580+ );
581+ }
582+}
Aschema-pikedefault / TopLevel.pmod+102 −0
@@ -0,0 +1,102 @@
1+// This source has been automatically generated by quicktype.
2+// ( https://github.com/quicktype/quicktype )
3+//
4+// To use this code, simply import it into your project as a Pike module.
5+// To JSON-encode your object, you can pass it to `Standards.JSON.encode`
6+// or call `encode_json` on it.
7+//
8+// To decode a JSON string, first pass it to `Standards.JSON.decode`,
9+// and then pass the result to `<YourClass>_from_JSON`.
10+// It will return an instance of <YourClass>.
11+// Bear in mind that these functions have unexpected behavior,
12+// and will likely throw an error, if the JSON string does not
13+// match the expected interface, even if the JSON itself is valid.
14+
15+class TopLevel {
16+ A a; // json: "a"
17+ B b; // json: "b"
18+
19+ string encode_json() {
20+ mapping(string:mixed) json = ([
21+ "a" : a,
22+ "b" : b,
23+ ]);
24+
25+ return Standards.JSON.encode(json);
26+ }
27+}
28+
29+TopLevel TopLevel_from_JSON(mixed json) {
30+ TopLevel retval = TopLevel();
31+
32+ retval.a = json["a"];
33+ retval.b = json["b"];
34+
35+ return retval;
36+}
37+
38+class A {
39+ array(C) in; // json: "in"
40+ string name; // json: "name"
41+
42+ string encode_json() {
43+ mapping(string:mixed) json = ([
44+ "in" : in,
45+ "name" : name,
46+ ]);
47+
48+ return Standards.JSON.encode(json);
49+ }
50+}
51+
52+A A_from_JSON(mixed json) {
53+ A retval = A();
54+
55+ retval.in = json["in"];
56+ retval.name = json["name"];
57+
58+ return retval;
59+}
60+
61+class C {
62+ string name; // json: "name"
63+
64+ string encode_json() {
65+ mapping(string:mixed) json = ([
66+ "name" : name,
67+ ]);
68+
69+ return Standards.JSON.encode(json);
70+ }
71+}
72+
73+C C_from_JSON(mixed json) {
74+ C retval = C();
75+
76+ retval.name = json["name"];
77+
78+ return retval;
79+}
80+
81+class B {
82+ string name; // json: "name"
83+ array(C) out; // json: "out"
84+
85+ string encode_json() {
86+ mapping(string:mixed) json = ([
87+ "name" : name,
88+ "out" : out,
89+ ]);
90+
91+ return Standards.JSON.encode(json);
92+ }
93+}
94+
95+B B_from_JSON(mixed json) {
96+ B retval = B();
97+
98+ retval.name = json["name"];
99+ retval.out = json["out"];
100+
101+ return retval;
102+}
Aschema-pythondefault / quicktype.py+125 −0
@@ -0,0 +1,125 @@
1+from dataclasses import dataclass
2+from typing import Any, TypeVar, Callable, Type, cast
3+
4+
5+T = TypeVar("T")
6+
7+
8+def from_str(x: Any) -> str:
9+ assert isinstance(x, str)
10+ return x
11+
12+
13+def from_list(f: Callable[[Any], T], x: Any) -> list[T]:
14+ assert isinstance(x, list)
15+ return [f(y) for y in x]
16+
17+
18+def to_class(c: Type[T], x: Any) -> dict:
19+ assert isinstance(x, c)
20+ return cast(Any, x).to_dict()
21+
22+
23+@dataclass
24+class C:
25+ name: str
26+
27+ @staticmethod
28+ def from_dict(obj: Any) -> 'C':
29+ assert isinstance(obj, dict)
30+ name = from_str(obj.get("name"))
31+ return C(name)
32+
33+ def to_dict(self) -> dict:
34+ result: dict = {}
35+ result["name"] = from_str(self.name)
36+ return result
37+
38+
39+@dataclass
40+class A:
41+ a_in: list[C]
42+ name: str
43+
44+ @staticmethod
45+ def from_dict(obj: Any) -> 'A':
46+ assert isinstance(obj, dict)
47+ a_in = from_list(C.from_dict, obj.get("in"))
48+ name = from_str(obj.get("name"))
49+ return A(a_in, name)
50+
51+ def to_dict(self) -> dict:
52+ result: dict = {}
53+ result["in"] = from_list(lambda x: to_class(C, x), self.a_in)
54+ result["name"] = from_str(self.name)
55+ return result
56+
57+
58+@dataclass
59+class B:
60+ name: str
61+ out: list[C]
62+
63+ @staticmethod
64+ def from_dict(obj: Any) -> 'B':
65+ assert isinstance(obj, dict)
66+ name = from_str(obj.get("name"))
67+ out = from_list(C.from_dict, obj.get("out"))
68+ return B(name, out)
69+
70+ def to_dict(self) -> dict:
71+ result: dict = {}
72+ result["name"] = from_str(self.name)
73+ result["out"] = from_list(lambda x: to_class(C, x), self.out)
74+ return result
75+
76+
77+@dataclass
78+class TopLevel:
79+ a: A
80+ b: B
81+
82+ @staticmethod
83+ def from_dict(obj: Any) -> 'TopLevel':
84+ assert isinstance(obj, dict)
85+ a = A.from_dict(obj.get("a"))
86+ b = B.from_dict(obj.get("b"))
87+ return TopLevel(a, b)
88+
89+ def to_dict(self) -> dict:
90+ result: dict = {}
91+ result["a"] = to_class(A, self.a)
92+ result["b"] = to_class(B, self.b)
93+ return result
94+
95+
96+def a_from_dict(s: Any) -> A:
97+ return A.from_dict(s)
98+
99+
100+def a_to_dict(x: A) -> Any:
101+ return to_class(A, x)
102+
103+
104+def b_from_dict(s: Any) -> B:
105+ return B.from_dict(s)
106+
107+
108+def b_to_dict(x: B) -> Any:
109+ return to_class(B, x)
110+
111+
112+def c_from_dict(s: Any) -> C:
113+ return C.from_dict(s)
114+
115+
116+def c_to_dict(x: C) -> Any:
117+ return to_class(C, x)
118+
119+
120+def top_level_from_dict(s: Any) -> TopLevel:
121+ return TopLevel.from_dict(s)
122+
123+
124+def top_level_to_dict(x: TopLevel) -> Any:
125+ return to_class(TopLevel, x)
Aschema-rubydefault / TopLevel.rb+138 −0
@@ -0,0 +1,138 @@
1+# This code may look unusually verbose for Ruby (and it is), but
2+# it performs some subtle and complex validation of JSON data.
3+#
4+# To parse this JSON, add 'dry-struct' and 'dry-types' gems, then do:
5+#
6+# a = A.from_json! "{…}"
7+# puts a.a_in.first.c_name
8+#
9+# b = B.from_json! "{…}"
10+# puts b.out.first.c_name
11+#
12+# c = C.from_json! "{…}"
13+# puts c.c_name
14+#
15+# top_level = TopLevel.from_json! "{…}"
16+# puts top_level.b.out.first.c_name
17+#
18+# If from_json! succeeds, the value returned matches the schema.
19+
20+require 'json'
21+require 'dry-types'
22+require 'dry-struct'
23+
24+module Types
25+ include Dry.Types(default: :nominal)
26+
27+ Hash = Strict::Hash
28+ String = Strict::String
29+end
30+
31+class C < Dry::Struct
32+ attribute :c_name, Types::String
33+
34+ def self.from_dynamic!(d)
35+ d = Types::Hash[d]
36+ new(
37+ c_name: d.fetch("name"),
38+ )
39+ end
40+
41+ def self.from_json!(json)
42+ from_dynamic!(JSON.parse(json))
43+ end
44+
45+ def to_dynamic
46+ {
47+ "name" => c_name,
48+ }
49+ end
50+
51+ def to_json(options = nil)
52+ JSON.generate(to_dynamic, options)
53+ end
54+end
55+
56+class A < Dry::Struct
57+ attribute :a_in, Types.Array(C)
58+ attribute :a_name, Types::String
59+
60+ def self.from_dynamic!(d)
61+ d = Types::Hash[d]
62+ new(
63+ a_in: d.fetch("in").map { |x| C.from_dynamic!(x) },
64+ a_name: d.fetch("name"),
65+ )
66+ end
67+
68+ def self.from_json!(json)
69+ from_dynamic!(JSON.parse(json))
70+ end
71+
72+ def to_dynamic
73+ {
74+ "in" => a_in.map { |x| x.to_dynamic },
75+ "name" => a_name,
76+ }
77+ end
78+
79+ def to_json(options = nil)
80+ JSON.generate(to_dynamic, options)
81+ end
82+end
83+
84+class B < Dry::Struct
85+ attribute :b_name, Types::String
86+ attribute :out, Types.Array(C)
87+
88+ def self.from_dynamic!(d)
89+ d = Types::Hash[d]
90+ new(
91+ b_name: d.fetch("name"),
92+ out: d.fetch("out").map { |x| C.from_dynamic!(x) },
93+ )
94+ end
95+
96+ def self.from_json!(json)
97+ from_dynamic!(JSON.parse(json))
98+ end
99+
100+ def to_dynamic
101+ {
102+ "name" => b_name,
103+ "out" => out.map { |x| x.to_dynamic },
104+ }
105+ end
106+
107+ def to_json(options = nil)
108+ JSON.generate(to_dynamic, options)
109+ end
110+end
111+
112+class TopLevel < Dry::Struct
113+ attribute :a, A
114+ attribute :b, B
115+
116+ def self.from_dynamic!(d)
117+ d = Types::Hash[d]
118+ new(
119+ a: A.from_dynamic!(d.fetch("a")),
120+ b: B.from_dynamic!(d.fetch("b")),
121+ )
122+ end
123+
124+ def self.from_json!(json)
125+ from_dynamic!(JSON.parse(json))
126+ end
127+
128+ def to_dynamic
129+ {
130+ "a" => a.to_dynamic,
131+ "b" => b.to_dynamic,
132+ }
133+ end
134+
135+ def to_json(options = nil)
136+ JSON.generate(to_dynamic, options)
137+ end
138+end
Aschema-rustdefault / module_under_test.rs+41 −0
@@ -0,0 +1,41 @@
1+// Example code that deserializes and serializes the model.
2+// extern crate serde;
3+// #[macro_use]
4+// extern crate serde_derive;
5+// extern crate serde_json;
6+//
7+// use generated_module::A;
8+//
9+// fn main() {
10+// let json = r#"{"answer": 42}"#;
11+// let model: A = serde_json::from_str(&json).unwrap();
12+// }
13+
14+use serde::{Serialize, Deserialize};
15+
16+#[derive(Debug, Clone, Serialize, Deserialize)]
17+pub struct TopLevel {
18+ pub a: A,
19+
20+ pub b: B,
21+}
22+
23+#[derive(Debug, Clone, Serialize, Deserialize)]
24+pub struct A {
25+ #[serde(rename = "in")]
26+ pub a_in: Vec<C>,
27+
28+ pub name: String,
29+}
30+
31+#[derive(Debug, Clone, Serialize, Deserialize)]
32+pub struct C {
33+ pub name: String,
34+}
35+
36+#[derive(Debug, Clone, Serialize, Deserialize)]
37+pub struct B {
38+ pub name: String,
39+
40+ pub out: Vec<C>,
41+}
Aschema-scala3-upickledefault / TopLevel.scala+85 −0
@@ -0,0 +1,85 @@
1+package quicktype
2+
3+// Custom pickler so that missing keys and JSON nulls both read as None,
4+// and None is left out when writing (upickle's default for Option is a
5+// JSON array).
6+object OptionPickler extends upickle.AttributeTagged:
7+ import upickle.default.Writer
8+ import upickle.default.Reader
9+ override implicit def OptionWriter[T: Writer]: Writer[Option[T]] =
10+ implicitly[Writer[T]].comap[Option[T]] {
11+ case None => null.asInstanceOf[T]
12+ case Some(x) => x
13+ }
14+
15+ override implicit def OptionReader[T: Reader]: Reader[Option[T]] = {
16+ new Reader.Delegate[Any, Option[T]](implicitly[Reader[T]].map(Some(_))){
17+ override def visitNull(index: Int) = None
18+ }
19+ }
20+end OptionPickler
21+
22+// If a union has a null in, then we'll need this too...
23+type NullValue = None.type
24+given OptionPickler.ReadWriter[NullValue] = OptionPickler.readwriter[ujson.Value].bimap[NullValue](
25+ _ => ujson.Null,
26+ json => if json.isNull then None else throw new upickle.core.Abort("not null")
27+)
28+
29+object JsonExt:
30+ val valueReader = OptionPickler.readwriter[ujson.Value]
31+
32+ // upickle's built-in primitive readers are lenient -- the numeric and
33+ // boolean readers accept strings, and the string reader accepts
34+ // numbers and booleans -- so untagged unions need strict readers to
35+ // pick the right member.
36+ val strictString: OptionPickler.Reader[String] = valueReader.map {
37+ case ujson.Str(s) => s
38+ case json => throw new upickle.core.Abort("expected string, got " + json)
39+ }
40+ val strictLong: OptionPickler.Reader[Long] = valueReader.map {
41+ case ujson.Num(n) if n.isWhole => n.toLong
42+ case json => throw new upickle.core.Abort("expected integer, got " + json)
43+ }
44+ val strictDouble: OptionPickler.Reader[Double] = valueReader.map {
45+ case ujson.Num(n) => n
46+ case json => throw new upickle.core.Abort("expected number, got " + json)
47+ }
48+ val strictBoolean: OptionPickler.Reader[Boolean] = valueReader.map {
49+ case ujson.Bool(b) => b
50+ case json => throw new upickle.core.Abort("expected boolean, got " + json)
51+ }
52+
53+ def badMerge[T](r1: => OptionPickler.Reader[?], rest: OptionPickler.Reader[?]*): OptionPickler.Reader[T] = valueReader.map { json =>
54+ var t: T | Null = null
55+ val stack = Vector.newBuilder[Throwable]
56+ (r1 +: rest).foreach { reader =>
57+ if t == null then
58+ try
59+ t = OptionPickler.read[T](json, trace = true)(using reader.asInstanceOf[OptionPickler.Reader[T]])
60+ catch
61+ case exc => stack += exc
62+ }
63+ if t != null then t.nn else throw new Exception(json.toString(), stack.result().headOption.getOrElse(null))
64+ }
65+end JsonExt
66+
67+
68+case class TopLevel (
69+ val a : A,
70+ val b : B
71+) derives OptionPickler.ReadWriter
72+
73+case class A (
74+ val in : Seq[C],
75+ val name : String
76+) derives OptionPickler.ReadWriter
77+
78+case class C (
79+ val name : String
80+) derives OptionPickler.ReadWriter
81+
82+case class B (
83+ val name : String,
84+ val out : Seq[C]
85+) derives OptionPickler.ReadWriter
Aschema-scala3default / TopLevel.scala+27 −0
@@ -0,0 +1,27 @@
1+package quicktype
2+
3+import io.circe.syntax._
4+import io.circe._
5+import cats.syntax.functor._
6+
7+// If a union has a null in, then we'll need this too...
8+type NullValue = None.type
9+
10+case class TopLevel (
11+ val a : A,
12+ val b : B
13+) derives Encoder.AsObject, Decoder
14+
15+case class A (
16+ val in : Seq[C],
17+ val name : String
18+) derives Encoder.AsObject, Decoder
19+
20+case class C (
21+ val name : String
22+) derives Encoder.AsObject, Decoder
23+
24+case class B (
25+ val name : String,
26+ val out : Seq[C]
27+) derives Encoder.AsObject, Decoder
Aschema-schemadefault / TopLevel.schema+75 −0
@@ -0,0 +1,75 @@
1+{
2+ "$schema": "http://json-schema.org/draft-06/schema#",
3+ "definitions": {
4+ "TopLevel": {
5+ "type": "object",
6+ "additionalProperties": {},
7+ "properties": {
8+ "a": {
9+ "$ref": "#/definitions/A"
10+ },
11+ "b": {
12+ "$ref": "#/definitions/B"
13+ }
14+ },
15+ "required": [
16+ "a",
17+ "b"
18+ ],
19+ "title": "TopLevel"
20+ },
21+ "A": {
22+ "type": "object",
23+ "additionalProperties": {},
24+ "properties": {
25+ "in": {
26+ "type": "array",
27+ "items": {
28+ "$ref": "#/definitions/C"
29+ }
30+ },
31+ "name": {
32+ "type": "string"
33+ }
34+ },
35+ "required": [
36+ "in",
37+ "name"
38+ ],
39+ "title": "A"
40+ },
41+ "C": {
42+ "type": "object",
43+ "additionalProperties": {},
44+ "properties": {
45+ "name": {
46+ "type": "string"
47+ }
48+ },
49+ "required": [
50+ "name"
51+ ],
52+ "title": "C"
53+ },
54+ "B": {
55+ "type": "object",
56+ "additionalProperties": {},
57+ "properties": {
58+ "name": {
59+ "type": "string"
60+ },
61+ "out": {
62+ "type": "array",
63+ "items": {
64+ "$ref": "#/definitions/C"
65+ }
66+ }
67+ },
68+ "required": [
69+ "name",
70+ "out"
71+ ],
72+ "title": "B"
73+ }
74+ }
75+}
Aschema-typescriptdefault / TopLevel.ts+241 −0
@@ -0,0 +1,241 @@
1+// To parse this data:
2+//
3+// import { Convert, A, B, C, TopLevel } from "./TopLevel";
4+//
5+// const a = Convert.toA(json);
6+// const b = Convert.toB(json);
7+// const c = Convert.toC(json);
8+// const topLevel = Convert.toTopLevel(json);
9+//
10+// These functions will throw an error if the JSON doesn't
11+// match the expected interface, even if the JSON is valid.
12+
13+export interface TopLevel {
14+ a: A;
15+ b: B;
16+ [property: string]: unknown;
17+}
18+
19+export interface A {
20+ in: C[];
21+ name: string;
22+ [property: string]: unknown;
23+}
24+
25+export interface C {
26+ name: string;
27+ [property: string]: unknown;
28+}
29+
30+export interface B {
31+ name: string;
32+ out: C[];
33+ [property: string]: unknown;
34+}
35+
36+// Converts JSON strings to/from your types
37+// and asserts the results of JSON.parse at runtime
38+export class Convert {
39+ public static toA(json: string): A {
40+ return cast(JSON.parse(json), r("A"));
41+ }
42+
43+ public static aToJson(value: A): string {
44+ return JSON.stringify(uncast(value, r("A")), null, 2);
45+ }
46+
47+ public static toB(json: string): B {
48+ return cast(JSON.parse(json), r("B"));
49+ }
50+
51+ public static bToJson(value: B): string {
52+ return JSON.stringify(uncast(value, r("B")), null, 2);
53+ }
54+
55+ public static toC(json: string): C {
56+ return cast(JSON.parse(json), r("C"));
57+ }
58+
59+ public static cToJson(value: C): string {
60+ return JSON.stringify(uncast(value, r("C")), null, 2);
61+ }
62+
63+ public static toTopLevel(json: string): TopLevel {
64+ return cast(JSON.parse(json), r("TopLevel"));
65+ }
66+
67+ public static topLevelToJson(value: TopLevel): string {
68+ return JSON.stringify(uncast(value, r("TopLevel")), null, 2);
69+ }
70+}
71+
72+function invalidValue(typ: any, val: any, key: any, parent: any = ''): never {
73+ const prettyTyp = prettyTypeName(typ);
74+ const parentText = parent ? ` on ${parent}` : '';
75+ const keyText = key ? ` for key "${key}"` : '';
76+ throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`);
77+}
78+
79+function prettyTypeName(typ: any): string {
80+ if (Array.isArray(typ)) {
81+ if (typ.length === 2 && typ[0] === undefined) {
82+ return `an optional ${prettyTypeName(typ[1])}`;
83+ } else {
84+ return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`;
85+ }
86+ } else if (typeof typ === "object" && typ.literal !== undefined) {
87+ return typ.literal;
88+ } else {
89+ return typeof typ;
90+ }
91+}
92+
93+function jsonToJSProps(typ: any): any {
94+ if (typ.jsonToJS === undefined) {
95+ const map: any = {};
96+ typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ });
97+ typ.jsonToJS = map;
98+ }
99+ return typ.jsonToJS;
100+}
101+
102+function jsToJSONProps(typ: any): any {
103+ if (typ.jsToJSON === undefined) {
104+ const map: any = {};
105+ typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ });
106+ typ.jsToJSON = map;
107+ }
108+ return typ.jsToJSON;
109+}
110+
111+function transform(val: any, typ: any, getProps: any, key: any = '', parent: any = ''): any {
112+ function transformPrimitive(typ: string, val: any): any {
113+ if (typeof typ === typeof val) return val;
114+ return invalidValue(typ, val, key, parent);
115+ }
116+
117+ function transformUnion(typs: any[], val: any): any {
118+ // val must validate against one typ in typs
119+ const l = typs.length;
120+ for (let i = 0; i < l; i++) {
121+ const typ = typs[i];
122+ try {
123+ return transform(val, typ, getProps);
124+ } catch (_) {}
125+ }
126+ return invalidValue(typs, val, key, parent);
127+ }
128+
129+ function transformEnum(cases: string[], val: any): any {
130+ if (cases.indexOf(val) !== -1) return val;
131+ return invalidValue(cases.map(a => { return l(a); }), val, key, parent);
132+ }
133+
134+ function transformArray(typ: any, val: any): any {
135+ // val must be an array with no invalid elements
136+ if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent);
137+ return val.map(el => transform(el, typ, getProps));
138+ }
139+
140+ function transformDate(val: any): any {
141+ if (val === null) {
142+ return null;
143+ }
144+ const d = new Date(val);
145+ if (isNaN(d.valueOf())) {
146+ return invalidValue(l("Date"), val, key, parent);
147+ }
148+ return d;
149+ }
150+
151+ function transformObject(props: { [k: string]: any }, additional: any, val: any): any {
152+ if (val === null || typeof val !== "object" || Array.isArray(val)) {
153+ return invalidValue(l(ref || "object"), val, key, parent);
154+ }
155+ const result: any = {};
156+ Object.getOwnPropertyNames(props).forEach(key => {
157+ const prop = props[key];
158+ const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined;
159+ result[prop.key] = transform(v, prop.typ, getProps, key, ref);
160+ });
161+ Object.getOwnPropertyNames(val).forEach(key => {
162+ if (!Object.prototype.hasOwnProperty.call(props, key)) {
163+ result[key] = transform(val[key], additional, getProps, key, ref);
164+ }
165+ });
166+ return result;
167+ }
168+
169+ if (typ === "any") return val;
170+ if (typ === null) {
171+ if (val === null) return val;
172+ return invalidValue(typ, val, key, parent);
173+ }
174+ if (typ === false) return invalidValue(typ, val, key, parent);
175+ let ref: any = undefined;
176+ while (typeof typ === "object" && typ.ref !== undefined) {
177+ ref = typ.ref;
178+ typ = typeMap[typ.ref];
179+ }
180+ if (Array.isArray(typ)) return transformEnum(typ, val);
181+ if (typeof typ === "object") {
182+ return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val)
183+ : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val)
184+ : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val)
185+ : invalidValue(typ, val, key, parent);
186+ }
187+ // Numbers can be parsed by Date but shouldn't be.
188+ if (typ === Date && typeof val !== "number") return transformDate(val);
189+ return transformPrimitive(typ, val);
190+}
191+
192+function cast<T>(val: any, typ: any): T {
193+ return transform(val, typ, jsonToJSProps);
194+}
195+
196+function uncast<T>(val: T, typ: any): any {
197+ return transform(val, typ, jsToJSONProps);
198+}
199+
200+function l(typ: any) {
201+ return { literal: typ };
202+}
203+
204+function a(typ: any) {
205+ return { arrayItems: typ };
206+}
207+
208+function u(...typs: any[]) {
209+ return { unionMembers: typs };
210+}
211+
212+function o(props: any[], additional: any) {
213+ return { props, additional };
214+}
215+
216+function m(additional: any) {
217+ const props: any[] = [];
218+ return { props, additional };
219+}
220+
221+function r(name: string) {
222+ return { ref: name };
223+}
224+
225+const typeMap: any = {
226+ "TopLevel": o([
227+ { json: "a", js: "a", typ: r("A") },
228+ { json: "b", js: "b", typ: r("B") },
229+ ], "any"),
230+ "A": o([
231+ { json: "in", js: "in", typ: a(r("C")) },
232+ { json: "name", js: "name", typ: "" },
233+ ], "any"),
234+ "C": o([
235+ { json: "name", js: "name", typ: "" },
236+ ], "any"),
237+ "B": o([
238+ { json: "name", js: "name", typ: "" },
239+ { json: "out", js: "out", typ: a(r("C")) },
240+ ], "any"),
241+};
No generated files match these filters.