Generated-output differences

quicktype output changed between the PR base and head revisions.
← Back to the pull request
35files differ
0modified
35new
0deleted
2,534changed lines
+2,534 −0insertions / deletions
Base 3061a7bd52c02eebde32dc0c6fb46069f0ebc0a4 · PR merge c1dd85946cdd9dc1cd8bfc75403b013a4f4b9733 · Head 8e08d942073cf9598d530c65b2e0da783463bd68 · raw patch
Aschema-cjson/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.c+128 −0
@@ -0,0 +1,128 @@
1+/**
2+ * TopLevel.c
3+ * This file has been autogenerated using quicktype https://github.com/quicktype/quicktype - DO NOT EDIT
4+ */
5+
6+#include "TopLevel.h"
7+
8+struct Committer * cJSON_ParseCommitter(const char * s) {
9+ struct Committer * x = NULL;
10+ if (NULL != s) {
11+ cJSON * j = cJSON_Parse(s);
12+ if (NULL != j) {
13+ x = cJSON_GetCommitterValue(j);
14+ cJSON_Delete(j);
15+ }
16+ }
17+ return x;
18+}
19+
20+struct Committer * cJSON_GetCommitterValue(const cJSON * j) {
21+ struct Committer * x = NULL;
22+ if (NULL != j) {
23+ if (NULL != (x = cJSON_malloc(sizeof(struct Committer)))) {
24+ memset(x, 0, sizeof(struct Committer));
25+ if (cJSON_HasObjectItem(j, "date")) {
26+ x->date = strdup(cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(j, "date")));
27+ }
28+ else {
29+ if (NULL != (x->date = cJSON_malloc(sizeof(char)))) {
30+ x->date[0] = '\0';
31+ }
32+ }
33+ }
34+ }
35+ return x;
36+}
37+
38+cJSON * cJSON_CreateCommitter(const struct Committer * x) {
39+ cJSON * j = NULL;
40+ if (NULL != x) {
41+ if (NULL != (j = cJSON_CreateObject())) {
42+ if (NULL != x->date) {
43+ cJSON_AddStringToObject(j, "date", x->date);
44+ }
45+ else {
46+ cJSON_AddStringToObject(j, "date", "");
47+ }
48+ }
49+ }
50+ return j;
51+}
52+
53+char * cJSON_PrintCommitter(const struct Committer * x) {
54+ char * s = NULL;
55+ if (NULL != x) {
56+ cJSON * j = cJSON_CreateCommitter(x);
57+ if (NULL != j) {
58+ s = cJSON_Print(j);
59+ cJSON_Delete(j);
60+ }
61+ }
62+ return s;
63+}
64+
65+void cJSON_DeleteCommitter(struct Committer * x) {
66+ if (NULL != x) {
67+ if (NULL != x->date) {
68+ cJSON_free(x->date);
69+ }
70+ cJSON_free(x);
71+ }
72+}
73+
74+struct TopLevel * cJSON_ParseTopLevel(const char * s) {
75+ struct TopLevel * x = NULL;
76+ if (NULL != s) {
77+ cJSON * j = cJSON_Parse(s);
78+ if (NULL != j) {
79+ x = cJSON_GetTopLevelValue(j);
80+ cJSON_Delete(j);
81+ }
82+ }
83+ return x;
84+}
85+
86+struct TopLevel * cJSON_GetTopLevelValue(const cJSON * j) {
87+ struct TopLevel * x = NULL;
88+ if (NULL != j) {
89+ if (NULL != (x = cJSON_malloc(sizeof(struct TopLevel)))) {
90+ memset(x, 0, sizeof(struct TopLevel));
91+ if (cJSON_HasObjectItem(j, "committer")) {
92+ x->committer = cJSON_GetCommitterValue(cJSON_GetObjectItemCaseSensitive(j, "committer"));
93+ }
94+ }
95+ }
96+ return x;
97+}
98+
99+cJSON * cJSON_CreateTopLevel(const struct TopLevel * x) {
100+ cJSON * j = NULL;
101+ if (NULL != x) {
102+ if (NULL != (j = cJSON_CreateObject())) {
103+ cJSON_AddItemToObject(j, "committer", cJSON_CreateCommitter(x->committer));
104+ }
105+ }
106+ return j;
107+}
108+
109+char * cJSON_PrintTopLevel(const struct TopLevel * x) {
110+ char * s = NULL;
111+ if (NULL != x) {
112+ cJSON * j = cJSON_CreateTopLevel(x);
113+ if (NULL != j) {
114+ s = cJSON_Print(j);
115+ cJSON_Delete(j);
116+ }
117+ }
118+ return s;
119+}
120+
121+void cJSON_DeleteTopLevel(struct TopLevel * x) {
122+ if (NULL != x) {
123+ if (NULL != x->committer) {
124+ cJSON_DeleteCommitter(x->committer);
125+ }
126+ cJSON_free(x);
127+ }
128+}
Aschema-cjson/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.h+61 −0
@@ -0,0 +1,61 @@
1+/**
2+ * TopLevel.h
3+ * This file has been autogenerated using quicktype https://github.com/quicktype/quicktype - DO NOT EDIT
4+ * This file depends of https://github.com/DaveGamble/cJSON, https://github.com/joelguittet/c-list and https://github.com/joelguittet/c-hashtable
5+ * To parse json data from json string use the following: struct <type> * data = cJSON_Parse<type>(<string>);
6+ * To get json data from cJSON object use the following: struct <type> * data = cJSON_Get<type>Value(<cjson>);
7+ * To get cJSON object from json data use the following: cJSON * cjson = cJSON_Create<type>(<data>);
8+ * To print json string from json data use the following: char * string = cJSON_Print<type>(<data>);
9+ * To delete json data use the following: cJSON_Delete<type>(<data>);
10+ */
11+
12+#ifndef __TOPLEVEL_H__
13+#define __TOPLEVEL_H__
14+
15+#ifdef __cplusplus
16+extern "C" {
17+#endif
18+
19+#include <stdint.h>
20+#include <stdbool.h>
21+#include <stdlib.h>
22+#include <string.h>
23+#include <cJSON.h>
24+#include <hashtable.h>
25+#include <list.h>
26+
27+#ifndef cJSON_Bool
28+#define cJSON_Bool (cJSON_True | cJSON_False)
29+#endif
30+#ifndef cJSON_Map
31+#define cJSON_Map (1 << 16)
32+#endif
33+#ifndef cJSON_Enum
34+#define cJSON_Enum (1 << 17)
35+#endif
36+
37+struct Committer {
38+ char * date;
39+};
40+
41+struct TopLevel {
42+ struct Committer * committer;
43+};
44+
45+struct Committer * cJSON_ParseCommitter(const char * s);
46+struct Committer * cJSON_GetCommitterValue(const cJSON * j);
47+cJSON * cJSON_CreateCommitter(const struct Committer * x);
48+char * cJSON_PrintCommitter(const struct Committer * x);
49+void cJSON_DeleteCommitter(struct Committer * x);
50+
51+struct TopLevel * cJSON_ParseTopLevel(const char * s);
52+struct TopLevel * cJSON_GetTopLevelValue(const cJSON * j);
53+cJSON * cJSON_CreateTopLevel(const struct TopLevel * x);
54+char * cJSON_PrintTopLevel(const struct TopLevel * x);
55+void cJSON_DeleteTopLevel(struct TopLevel * x);
56+
57+#ifdef __cplusplus
58+}
59+#endif
60+
61+#endif /* __TOPLEVEL_H__ */
Aschema-cplusplus/test/inputs/schema/transformed-string-intersection.schema/default/quicktype.hpp+87 −0
@@ -0,0 +1,87 @@
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+// TopLevel data = nlohmann::json::parse(jsonString);
8+
9+#pragma once
10+
11+#include "json.hpp"
12+
13+#include <optional>
14+#include <stdexcept>
15+#include <regex>
16+
17+namespace quicktype {
18+ using nlohmann::json;
19+
20+ #ifndef NLOHMANN_UNTYPED_quicktype_HELPER
21+ #define NLOHMANN_UNTYPED_quicktype_HELPER
22+ inline json get_untyped(const json & j, const char * property) {
23+ if (j.find(property) != j.end()) {
24+ return j.at(property).get<json>();
25+ }
26+ return json();
27+ }
28+
29+ inline json get_untyped(const json & j, std::string property) {
30+ return get_untyped(j, property.data());
31+ }
32+ #endif
33+
34+ class Committer {
35+ public:
36+ Committer() = default;
37+ virtual ~Committer() = default;
38+
39+ private:
40+ std::string date;
41+
42+ public:
43+ const std::string & get_date() const { return date; }
44+ std::string & get_mutable_date() { return date; }
45+ void set_date(const std::string & value) { this->date = value; }
46+ };
47+
48+ class TopLevel {
49+ public:
50+ TopLevel() = default;
51+ virtual ~TopLevel() = default;
52+
53+ private:
54+ Committer committer;
55+
56+ public:
57+ const Committer & get_committer() const { return committer; }
58+ Committer & get_mutable_committer() { return committer; }
59+ void set_committer(const Committer & value) { this->committer = value; }
60+ };
61+}
62+
63+namespace quicktype {
64+ void from_json(const json & j, Committer & x);
65+ void to_json(json & j, const Committer & x);
66+
67+ void from_json(const json & j, TopLevel & x);
68+ void to_json(json & j, const TopLevel & x);
69+
70+ inline void from_json(const json & j, Committer& x) {
71+ x.set_date(j.at("date").get<std::string>());
72+ }
73+
74+ inline void to_json(json & j, const Committer & x) {
75+ j = json::object();
76+ j["date"] = x.get_date();
77+ }
78+
79+ inline void from_json(const json & j, TopLevel& x) {
80+ x.set_committer(j.at("committer").get<Committer>());
81+ }
82+
83+ inline void to_json(json & j, const TopLevel & x) {
84+ j = json::object();
85+ j["committer"] = x.get_committer();
86+ }
87+}
Aschema-csharp-SystemTextJson/test/inputs/schema/transformed-string-intersection.schema/default/QuickType.cs+67 −0
@@ -0,0 +1,67 @@
1+// <auto-generated />
2+//
3+// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
4+//
5+// using QuickType;
6+//
7+// var topLevel = TopLevel.FromJson(jsonString);
8+#nullable enable
9+#pragma warning disable CS8618
10+#pragma warning disable CS8601
11+#pragma warning disable CS8602
12+#pragma warning disable CS8603
13+#pragma warning disable CS8604
14+#pragma warning disable CS8625
15+#pragma warning disable CS8765
16+
17+namespace QuickType
18+{
19+ using System;
20+ using System.Collections.Generic;
21+
22+ using System.Globalization;
23+ using Newtonsoft.Json;
24+ using Newtonsoft.Json.Converters;
25+
26+ public partial class TopLevel
27+ {
28+ [JsonProperty("committer", Required = Required.Always)]
29+ public Committer Committer { get; set; }
30+ }
31+
32+ public partial class Committer
33+ {
34+ [JsonProperty("date", Required = Required.Always)]
35+ public DateTimeOffset Date { get; set; }
36+ }
37+
38+ public partial class TopLevel
39+ {
40+ public static TopLevel FromJson(string json) => JsonConvert.DeserializeObject<TopLevel>(json, QuickType.Converter.Settings);
41+ }
42+
43+ public static partial class Serialize
44+ {
45+ public static string ToJson(this TopLevel self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
46+ }
47+
48+ internal static partial class Converter
49+ {
50+ public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
51+ {
52+ MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
53+ DateParseHandling = DateParseHandling.None,
54+ Converters =
55+ {
56+ new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
57+ },
58+ };
59+ }
60+}
61+#pragma warning restore CS8618
62+#pragma warning restore CS8601
63+#pragma warning restore CS8602
64+#pragma warning restore CS8603
65+#pragma warning restore CS8604
66+#pragma warning restore CS8625
67+#pragma warning restore CS8765
Aschema-csharp/test/inputs/schema/transformed-string-intersection.schema/default/QuickType.cs+173 −0
@@ -0,0 +1,173 @@
1+// <auto-generated />
2+//
3+// To parse this JSON data, add NuGet 'System.Text.Json' then do:
4+//
5+// using QuickType;
6+//
7+// var topLevel = TopLevel.FromJson(jsonString);
8+#nullable enable
9+#pragma warning disable CS8618
10+#pragma warning disable CS8601
11+#pragma warning disable CS8602
12+#pragma warning disable CS8603
13+
14+namespace QuickType
15+{
16+ using System;
17+ using System.Collections.Generic;
18+
19+ using System.Text.Json;
20+ using System.Text.Json.Serialization;
21+ using System.Globalization;
22+
23+ public partial class TopLevel
24+ {
25+ [JsonRequired]
26+ [JsonPropertyName("committer")]
27+ public Committer Committer { get; set; }
28+ }
29+
30+ public partial class Committer
31+ {
32+ [JsonRequired]
33+ [JsonPropertyName("date")]
34+ public DateTimeOffset Date { get; set; }
35+ }
36+
37+ public partial class TopLevel
38+ {
39+ public static TopLevel FromJson(string json) => JsonSerializer.Deserialize<TopLevel>(json, QuickType.Converter.Settings);
40+ }
41+
42+ public static partial class Serialize
43+ {
44+ public static string ToJson(this TopLevel self) => JsonSerializer.Serialize(self, QuickType.Converter.Settings);
45+ }
46+
47+ internal static partial class Converter
48+ {
49+ public static readonly JsonSerializerOptions Settings = new(JsonSerializerDefaults.General)
50+ {
51+ Converters =
52+ {
53+ new DateOnlyConverter(),
54+ new TimeOnlyConverter(),
55+ IsoDateTimeOffsetConverter.Singleton
56+ },
57+ };
58+ }
59+
60+ public class DateOnlyConverter : JsonConverter<DateOnly>
61+ {
62+ private readonly string serializationFormat;
63+ public DateOnlyConverter() : this(null) { }
64+
65+ public DateOnlyConverter(string? serializationFormat)
66+ {
67+ this.serializationFormat = serializationFormat ?? "yyyy-MM-dd";
68+ }
69+
70+ public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
71+ {
72+ var value = reader.GetString();
73+ return DateOnly.Parse(value!);
74+ }
75+
76+ public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
77+ => writer.WriteStringValue(value.ToString(serializationFormat));
78+ }
79+
80+ public class TimeOnlyConverter : JsonConverter<TimeOnly>
81+ {
82+ private readonly string serializationFormat;
83+
84+ public TimeOnlyConverter() : this(null) { }
85+
86+ public TimeOnlyConverter(string? serializationFormat)
87+ {
88+ this.serializationFormat = serializationFormat ?? "HH:mm:ss.fff";
89+ }
90+
91+ public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
92+ {
93+ var value = reader.GetString();
94+ return TimeOnly.Parse(value!);
95+ }
96+
97+ public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options)
98+ => writer.WriteStringValue(value.ToString(serializationFormat));
99+ }
100+
101+ internal class IsoDateTimeOffsetConverter : JsonConverter<DateTimeOffset>
102+ {
103+ public override bool CanConvert(Type t) => t == typeof(DateTimeOffset);
104+
105+ private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
106+
107+ private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
108+ private string? _dateTimeFormat;
109+ private CultureInfo? _culture;
110+
111+ public DateTimeStyles DateTimeStyles
112+ {
113+ get => _dateTimeStyles;
114+ set => _dateTimeStyles = value;
115+ }
116+
117+ public string? DateTimeFormat
118+ {
119+ get => _dateTimeFormat ?? string.Empty;
120+ set => _dateTimeFormat = (string.IsNullOrEmpty(value)) ? null : value;
121+ }
122+
123+ public CultureInfo Culture
124+ {
125+ get => _culture ?? CultureInfo.CurrentCulture;
126+ set => _culture = value;
127+ }
128+
129+ public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
130+ {
131+ string text;
132+
133+
134+ if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
135+ || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
136+ {
137+ value = value.ToUniversalTime();
138+ }
139+
140+ text = value.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
141+
142+ writer.WriteStringValue(text);
143+ }
144+
145+ public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
146+ {
147+ string? dateText = reader.GetString();
148+
149+ if (string.IsNullOrEmpty(dateText) == false)
150+ {
151+ if (!string.IsNullOrEmpty(_dateTimeFormat))
152+ {
153+ return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
154+ }
155+ else
156+ {
157+ return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
158+ }
159+ }
160+ else
161+ {
162+ return default(DateTimeOffset);
163+ }
164+ }
165+
166+
167+ public static readonly IsoDateTimeOffsetConverter Singleton = new IsoDateTimeOffsetConverter();
168+ }
169+}
170+#pragma warning restore CS8618
171+#pragma warning restore CS8601
172+#pragma warning restore CS8602
173+#pragma warning restore CS8603
Aschema-dart/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.dart+41 −0
@@ -0,0 +1,41 @@
1+// To parse this JSON data, do
2+//
3+// final topLevel = topLevelFromJson(jsonString);
4+
5+import 'dart:convert';
6+
7+TopLevel topLevelFromJson(String str) => TopLevel.fromJson(json.decode(str));
8+
9+String topLevelToJson(TopLevel data) => json.encode(data.toJson());
10+
11+class TopLevel {
12+ final Committer committer;
13+
14+ TopLevel({
15+ required this.committer,
16+ });
17+
18+ factory TopLevel.fromJson(Map<String, dynamic> json) => TopLevel(
19+ committer: Committer.fromJson(json["committer"]),
20+ );
21+
22+ Map<String, dynamic> toJson() => {
23+ "committer": committer.toJson(),
24+ };
25+}
26+
27+class Committer {
28+ final DateTime date;
29+
30+ Committer({
31+ required this.date,
32+ });
33+
34+ factory Committer.fromJson(Map<String, dynamic> json) => Committer(
35+ date: DateTime.parse(json["date"]),
36+ );
37+
38+ Map<String, dynamic> toJson() => {
39+ "date": date.toIso8601String(),
40+ };
41+}
Aschema-elixir/test/inputs/schema/transformed-string-intersection.schema/default/QuickType.ex+72 −0
@@ -0,0 +1,72 @@
1+# This file was autogenerated using quicktype https://github.com/quicktype/quicktype
2+#
3+# Add Jason to your mix.exs
4+#
5+# Decode a JSON string: TopLevel.from_json(data)
6+# Encode into a JSON string: TopLevel.to_json(struct)
7+
8+defmodule Committer do
9+ @enforce_keys [:date]
10+ defstruct [:date]
11+
12+ @type t :: %__MODULE__{
13+ date: String.t()
14+ }
15+
16+ def from_map(m) do
17+ %Committer{
18+ date: m["date"],
19+ }
20+ end
21+
22+ def from_json(json) do
23+ json
24+ |> Jason.decode!()
25+ |> from_map()
26+ end
27+
28+ def to_map(struct) do
29+ %{
30+ "date" => struct.date,
31+ }
32+ end
33+
34+ def to_json(struct) do
35+ struct
36+ |> to_map()
37+ |> Jason.encode!()
38+ end
39+end
40+
41+defmodule TopLevel do
42+ @enforce_keys [:committer]
43+ defstruct [:committer]
44+
45+ @type t :: %__MODULE__{
46+ committer: Committer.t()
47+ }
48+
49+ def from_map(m) do
50+ %TopLevel{
51+ committer: Committer.from_map(m["committer"]),
52+ }
53+ end
54+
55+ def from_json(json) do
56+ json
57+ |> Jason.decode!()
58+ |> from_map()
59+ end
60+
61+ def to_map(struct) do
62+ %{
63+ "committer" => Committer.to_map(struct.committer),
64+ }
65+ end
66+
67+ def to_json(struct) do
68+ struct
69+ |> to_map()
70+ |> Jason.encode!()
71+ end
72+end
Aschema-elm/test/inputs/schema/transformed-string-intersection.schema/default/QuickType.elm+67 −0
@@ -0,0 +1,67 @@
1+-- To decode the JSON data, add this file to your project, run
2+--
3+-- elm install NoRedInk/elm-json-decode-pipeline
4+--
5+-- add these imports
6+--
7+-- import Json.Decode exposing (decodeString)
8+-- import QuickType exposing (quickType)
9+--
10+-- and you're off to the races with
11+--
12+-- decodeString quickType myJsonString
13+
14+module QuickType exposing
15+ ( QuickType
16+ , quickTypeToString
17+ , quickType
18+ , Committer
19+ )
20+
21+import Json.Decode as Jdec
22+import Json.Decode.Pipeline as Jpipe
23+import Json.Encode as Jenc
24+import Dict exposing (Dict)
25+
26+type alias QuickType =
27+ { committer : Committer
28+ }
29+
30+type alias Committer =
31+ { date : String
32+ }
33+
34+-- decoders and encoders
35+
36+quickTypeToString : QuickType -> String
37+quickTypeToString r = Jenc.encode 0 (encodeQuickType r)
38+
39+quickType : Jdec.Decoder QuickType
40+quickType =
41+ Jdec.succeed QuickType
42+ |> Jpipe.required "committer" committer
43+
44+encodeQuickType : QuickType -> Jenc.Value
45+encodeQuickType x =
46+ Jenc.object
47+ [ ("committer", encodeCommitter x.committer)
48+ ]
49+
50+committer : Jdec.Decoder Committer
51+committer =
52+ Jdec.succeed Committer
53+ |> Jpipe.required "date" Jdec.string
54+
55+encodeCommitter : Committer -> Jenc.Value
56+encodeCommitter x =
57+ Jenc.object
58+ [ ("date", Jenc.string x.date)
59+ ]
60+
61+--- encoder helpers
62+
63+makeNullableEncoder : (a -> Jenc.Value) -> Maybe a -> Jenc.Value
64+makeNullableEncoder f m =
65+ case m of
66+ Just x -> f x
67+ Nothing -> Jenc.null
Aschema-flow/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.js+197 −0
@@ -0,0 +1,197 @@
1+// @flow
2+
3+// To parse this data:
4+//
5+// const Convert = require("./TopLevel");
6+//
7+// const topLevel = Convert.toTopLevel(json);
8+//
9+// These functions will throw an error if the JSON doesn't
10+// match the expected interface, even if the JSON is valid.
11+
12+export type TopLevel = {
13+ committer: Committer;
14+ [property: string]: mixed;
15+};
16+
17+export type Committer = {
18+ date: Date;
19+ [property: string]: mixed;
20+};
21+
22+// Converts JSON strings to/from your types
23+// and asserts the results of JSON.parse at runtime
24+function toTopLevel(json: string): TopLevel {
25+ return cast(JSON.parse(json), r("TopLevel"));
26+}
27+
28+function topLevelToJson(value: TopLevel): string {
29+ return JSON.stringify(uncast(value, r("TopLevel")), null, 2);
30+}
31+
32+function invalidValue(typ: any, val: any, key: any, parent: any = '') {
33+ const prettyTyp = prettyTypeName(typ);
34+ const parentText = parent ? ` on ${parent}` : '';
35+ const keyText = key ? ` for key "${key}"` : '';
36+ throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`);
37+}
38+
39+function prettyTypeName(typ: any): string {
40+ if (Array.isArray(typ)) {
41+ if (typ.length === 2 && typ[0] === undefined) {
42+ return `an optional ${prettyTypeName(typ[1])}`;
43+ } else {
44+ return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`;
45+ }
46+ } else if (typeof typ === "object" && typ.literal !== undefined) {
47+ return typ.literal;
48+ } else {
49+ return typeof typ;
50+ }
51+}
52+
53+function jsonToJSProps(typ: any): any {
54+ if (typ.jsonToJS === undefined) {
55+ const map: any = {};
56+ typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ });
57+ typ.jsonToJS = map;
58+ }
59+ return typ.jsonToJS;
60+}
61+
62+function jsToJSONProps(typ: any): any {
63+ if (typ.jsToJSON === undefined) {
64+ const map: any = {};
65+ typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ });
66+ typ.jsToJSON = map;
67+ }
68+ return typ.jsToJSON;
69+}
70+
71+function transform(val: any, typ: any, getProps: any, key: any = '', parent: any = ''): any {
72+ function transformPrimitive(typ: string, val: any): any {
73+ if (typeof typ === typeof val) return val;
74+ return invalidValue(typ, val, key, parent);
75+ }
76+
77+ function transformUnion(typs: any[], val: any): any {
78+ // val must validate against one typ in typs
79+ const l = typs.length;
80+ for (let i = 0; i < l; i++) {
81+ const typ = typs[i];
82+ try {
83+ return transform(val, typ, getProps);
84+ } catch (_) {}
85+ }
86+ return invalidValue(typs, val, key, parent);
87+ }
88+
89+ function transformEnum(cases: string[], val: any): any {
90+ if (cases.indexOf(val) !== -1) return val;
91+ return invalidValue(cases.map(a => { return l(a); }), val, key, parent);
92+ }
93+
94+ function transformArray(typ: any, val: any): any {
95+ // val must be an array with no invalid elements
96+ if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent);
97+ return val.map(el => transform(el, typ, getProps));
98+ }
99+
100+ function transformDate(val: any): any {
101+ if (val === null) {
102+ return null;
103+ }
104+ const d = new Date(val);
105+ if (isNaN(d.valueOf())) {
106+ return invalidValue(l("Date"), val, key, parent);
107+ }
108+ return d;
109+ }
110+
111+ function transformObject(props: { [k: string]: any }, additional: any, val: any): any {
112+ if (val === null || typeof val !== "object" || Array.isArray(val)) {
113+ return invalidValue(l(ref || "object"), val, key, parent);
114+ }
115+ const result: any = {};
116+ Object.getOwnPropertyNames(props).forEach(key => {
117+ const prop = props[key];
118+ const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined;
119+ result[prop.key] = transform(v, prop.typ, getProps, key, ref);
120+ });
121+ Object.getOwnPropertyNames(val).forEach(key => {
122+ if (!Object.prototype.hasOwnProperty.call(props, key)) {
123+ result[key] = transform(val[key], additional, getProps, key, ref);
124+ }
125+ });
126+ return result;
127+ }
128+
129+ if (typ === "any") return val;
130+ if (typ === null) {
131+ if (val === null) return val;
132+ return invalidValue(typ, val, key, parent);
133+ }
134+ if (typ === false) return invalidValue(typ, val, key, parent);
135+ let ref: any = undefined;
136+ while (typeof typ === "object" && typ.ref !== undefined) {
137+ ref = typ.ref;
138+ typ = typeMap[typ.ref];
139+ }
140+ if (Array.isArray(typ)) return transformEnum(typ, val);
141+ if (typeof typ === "object") {
142+ return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val)
143+ : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val)
144+ : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val)
145+ : invalidValue(typ, val, key, parent);
146+ }
147+ // Numbers can be parsed by Date but shouldn't be.
148+ if (typ === Date && typeof val !== "number") return transformDate(val);
149+ return transformPrimitive(typ, val);
150+}
151+
152+function cast<T>(val: any, typ: any): T {
153+ return transform(val, typ, jsonToJSProps);
154+}
155+
156+function uncast<T>(val: T, typ: any): any {
157+ return transform(val, typ, jsToJSONProps);
158+}
159+
160+function l(typ: any) {
161+ return { literal: typ };
162+}
163+
164+function a(typ: any) {
165+ return { arrayItems: typ };
166+}
167+
168+function u(...typs: any[]) {
169+ return { unionMembers: typs };
170+}
171+
172+function o(props: any[], additional: any) {
173+ return { props, additional };
174+}
175+
176+function m(additional: any) {
177+ const props: any[] = [];
178+ return { props, additional };
179+}
180+
181+function r(name: string) {
182+ return { ref: name };
183+}
184+
185+const typeMap: any = {
186+ "TopLevel": o([
187+ { json: "committer", js: "committer", typ: r("Committer") },
188+ ], "any"),
189+ "Committer": o([
190+ { json: "date", js: "date", typ: Date },
191+ ], "any"),
192+};
193+
194+module.exports = {
195+ "topLevelToJson": topLevelToJson,
196+ "toTopLevel": toTopLevel,
197+};
Aschema-golang/test/inputs/schema/transformed-string-intersection.schema/default/quicktype.go+29 −0
@@ -0,0 +1,29 @@
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+// topLevel, err := UnmarshalTopLevel(bytes)
5+// bytes, err = topLevel.Marshal()
6+
7+package main
8+
9+import "time"
10+
11+import "encoding/json"
12+
13+func UnmarshalTopLevel(data []byte) (TopLevel, error) {
14+ var r TopLevel
15+ err := json.Unmarshal(data, &r)
16+ return r, err
17+}
18+
19+func (r *TopLevel) Marshal() ([]byte, error) {
20+ return json.Marshal(r)
21+}
22+
23+type TopLevel struct {
24+ Committer Committer `json:"committer"`
25+}
26+
27+type Committer struct {
28+ Date time.Time `json:"date"`
29+}
Aschema-haskell/test/inputs/schema/transformed-string-intersection.schema/default/QuickType.hs+45 −0
@@ -0,0 +1,45 @@
1+{-# LANGUAGE StrictData #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+
4+module QuickType
5+ ( QuickType (..)
6+ , Committer (..)
7+ , decodeTopLevel
8+ ) where
9+
10+import Data.Aeson
11+import Data.Aeson.Types (emptyObject)
12+import Data.ByteString.Lazy (ByteString)
13+import Data.HashMap.Strict (HashMap)
14+import Data.Text (Text)
15+
16+data QuickType = QuickType
17+ { committerQuickType :: Committer
18+ } deriving (Show)
19+
20+data Committer = Committer
21+ { dateCommitter :: Text
22+ } deriving (Show)
23+
24+decodeTopLevel :: ByteString -> Maybe QuickType
25+decodeTopLevel = decode
26+
27+instance ToJSON QuickType where
28+ toJSON (QuickType committerQuickType) =
29+ object
30+ [ "committer" .= committerQuickType
31+ ]
32+
33+instance FromJSON QuickType where
34+ parseJSON (Object v) = QuickType
35+ <$> v .: "committer"
36+
37+instance ToJSON Committer where
38+ toJSON (Committer dateCommitter) =
39+ object
40+ [ "date" .= dateCommitter
41+ ]
42+
43+instance FromJSON Committer where
44+ parseJSON (Object v) = Committer
45+ <$> v .: "date"
Aschema-java-datetime-legacy/test/inputs/schema/transformed-string-intersection.schema/default/src/main/java/io/quicktype/Committer.java+13 −0
@@ -0,0 +1,13 @@
1+package io.quicktype;
2+
3+import com.fasterxml.jackson.annotation.*;
4+import java.time.OffsetDateTime;
5+
6+public class Committer {
7+ private OffsetDateTime date;
8+
9+ @JsonProperty("date")
10+ public OffsetDateTime getDate() { return date; }
11+ @JsonProperty("date")
12+ public void setDate(OffsetDateTime value) { this.date = value; }
13+}
Aschema-java-datetime-legacy/test/inputs/schema/transformed-string-intersection.schema/default/src/main/java/io/quicktype/Converter.java+101 −0
@@ -0,0 +1,101 @@
1+// To use this code, add the following Maven dependency to your project:
2+//
3+//
4+// com.fasterxml.jackson.core : jackson-databind : 2.9.0
5+// com.fasterxml.jackson.datatype : jackson-datatype-jsr310 : 2.9.0
6+//
7+// Import this package:
8+//
9+// import io.quicktype.Converter;
10+//
11+// Then you can deserialize a JSON string with
12+//
13+// TopLevel data = Converter.fromJsonString(jsonString);
14+
15+package io.quicktype;
16+
17+import java.io.IOException;
18+import com.fasterxml.jackson.databind.*;
19+import com.fasterxml.jackson.databind.module.SimpleModule;
20+import com.fasterxml.jackson.core.JsonParser;
21+import com.fasterxml.jackson.core.JsonProcessingException;
22+import java.util.*;
23+import java.time.LocalDate;
24+import java.time.OffsetDateTime;
25+import java.time.OffsetTime;
26+import java.time.ZoneOffset;
27+import java.time.ZonedDateTime;
28+import java.time.format.DateTimeFormatter;
29+import java.time.format.DateTimeFormatterBuilder;
30+import java.time.temporal.ChronoField;
31+
32+public class Converter {
33+ // Date-time helpers
34+
35+ private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
36+ .appendOptional(DateTimeFormatter.ISO_DATE_TIME)
37+ .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
38+ .appendOptional(DateTimeFormatter.ISO_INSTANT)
39+ .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SX"))
40+ .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssX"))
41+ .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
42+ .toFormatter()
43+ .withZone(ZoneOffset.UTC);
44+
45+ public static OffsetDateTime parseDateTimeString(String str) {
46+ return ZonedDateTime.from(Converter.DATE_TIME_FORMATTER.parse(str)).toOffsetDateTime();
47+ }
48+
49+ private static final DateTimeFormatter TIME_FORMATTER = new DateTimeFormatterBuilder()
50+ .appendOptional(DateTimeFormatter.ISO_TIME)
51+ .appendOptional(DateTimeFormatter.ISO_OFFSET_TIME)
52+ .parseDefaulting(ChronoField.YEAR, 2020)
53+ .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
54+ .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
55+ .toFormatter()
56+ .withZone(ZoneOffset.UTC);
57+
58+ public static OffsetTime parseTimeString(String str) {
59+ return ZonedDateTime.from(Converter.TIME_FORMATTER.parse(str)).toOffsetDateTime().toOffsetTime();
60+ }
61+ // Serialize/deserialize helpers
62+
63+ public static TopLevel fromJsonString(String json) throws IOException {
64+ return getObjectReader().readValue(json);
65+ }
66+
67+ public static String toJsonString(TopLevel obj) throws JsonProcessingException {
68+ return getObjectWriter().writeValueAsString(obj);
69+ }
70+
71+ private static ObjectReader reader;
72+ private static ObjectWriter writer;
73+
74+ private static void instantiateMapper() {
75+ ObjectMapper mapper = new ObjectMapper();
76+ mapper.findAndRegisterModules();
77+ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
78+ mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
79+ SimpleModule module = new SimpleModule();
80+ module.addDeserializer(OffsetDateTime.class, new JsonDeserializer<OffsetDateTime>() {
81+ @Override
82+ public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
83+ String value = jsonParser.getText();
84+ return Converter.parseDateTimeString(value);
85+ }
86+ });
87+ mapper.registerModule(module);
88+ reader = mapper.readerFor(TopLevel.class);
89+ writer = mapper.writerFor(TopLevel.class);
90+ }
91+
92+ private static ObjectReader getObjectReader() {
93+ if (reader == null) instantiateMapper();
94+ return reader;
95+ }
96+
97+ private static ObjectWriter getObjectWriter() {
98+ if (writer == null) instantiateMapper();
99+ return writer;
100+ }
101+}
Aschema-java-datetime-legacy/test/inputs/schema/transformed-string-intersection.schema/default/src/main/java/io/quicktype/TopLevel.java+12 −0
@@ -0,0 +1,12 @@
1+package io.quicktype;
2+
3+import com.fasterxml.jackson.annotation.*;
4+
5+public class TopLevel {
6+ private Committer committer;
7+
8+ @JsonProperty("committer")
9+ public Committer getCommitter() { return committer; }
10+ @JsonProperty("committer")
11+ public void setCommitter(Committer value) { this.committer = value; }
12+}
Aschema-java-lombok/test/inputs/schema/transformed-string-intersection.schema/default/src/main/java/io/quicktype/Committer.java+15 −0
@@ -0,0 +1,15 @@
1+package io.quicktype;
2+
3+import com.fasterxml.jackson.annotation.*;
4+import java.util.Date;
5+
6+public class Committer {
7+ private Date date;
8+
9+ @JsonProperty("date")
10+ @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssX", timezone = "UTC")
11+ public Date getDate() { return date; }
12+ @JsonProperty("date")
13+ @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssX", timezone = "UTC")
14+ public void setDate(Date value) { this.date = value; }
15+}
Aschema-java-lombok/test/inputs/schema/transformed-string-intersection.schema/default/src/main/java/io/quicktype/Converter.java+121 −0
@@ -0,0 +1,121 @@
1+// To use this code, add the following Maven dependency to your project:
2+//
3+//
4+// com.fasterxml.jackson.core : jackson-databind : 2.9.0
5+//
6+//
7+// Import this package:
8+//
9+// import io.quicktype.Converter;
10+//
11+// Then you can deserialize a JSON string with
12+//
13+// TopLevel data = Converter.fromJsonString(jsonString);
14+
15+package io.quicktype;
16+
17+import java.io.IOException;
18+import com.fasterxml.jackson.databind.*;
19+import com.fasterxml.jackson.databind.module.SimpleModule;
20+import com.fasterxml.jackson.core.JsonParser;
21+import com.fasterxml.jackson.core.JsonProcessingException;
22+import java.util.*;
23+import java.util.Date;
24+import java.text.SimpleDateFormat;
25+
26+public class Converter {
27+ // Date-time helpers
28+
29+ private static final String[] DATE_TIME_FORMATS = {
30+ "yyyy-MM-dd'T'HH:mm:ss.SX",
31+ "yyyy-MM-dd'T'HH:mm:ss.S",
32+ "yyyy-MM-dd'T'HH:mm:ssX",
33+ "yyyy-MM-dd'T'HH:mm:ss",
34+ "yyyy-MM-dd HH:mm:ss.SX",
35+ "yyyy-MM-dd HH:mm:ss.S",
36+ "yyyy-MM-dd HH:mm:ssX",
37+ "yyyy-MM-dd HH:mm:ss",
38+ "HH:mm:ss.SZ",
39+ "HH:mm:ss.S",
40+ "HH:mm:ssZ",
41+ "HH:mm:ss",
42+ "yyyy-MM-dd",
43+ };
44+
45+ public static Date parseAllDateTimeString(String str) {
46+ for (String format : DATE_TIME_FORMATS) {
47+ try {
48+ return new SimpleDateFormat(format).parse(str);
49+ } catch (Exception ex) {
50+ // Ignored
51+ }
52+ }
53+ return null;
54+ }
55+
56+ public static String serializeDateTime(Date datetime) {
57+ return new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ").format(datetime);
58+ }
59+
60+ public static String serializeDate(Date datetime) {
61+ return new SimpleDateFormat("yyyy-MM-dd").format(datetime);
62+ }
63+
64+ public static String serializeTime(Date datetime) {
65+ return new SimpleDateFormat("hh:mm:ssZ").format(datetime);
66+ }
67+ // Serialize/deserialize helpers
68+
69+ public static TopLevel fromJsonString(String json) throws IOException {
70+ return getObjectReader().readValue(json);
71+ }
72+
73+ public static String toJsonString(TopLevel obj) throws JsonProcessingException {
74+ return getObjectWriter().writeValueAsString(obj);
75+ }
76+
77+ private static ObjectReader reader;
78+ private static ObjectWriter writer;
79+
80+ private static void instantiateMapper() {
81+ ObjectMapper mapper = new ObjectMapper();
82+ mapper.findAndRegisterModules();
83+ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
84+ mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
85+ SimpleModule module = new SimpleModule();
86+ module.addDeserializer(Date.class, new JsonDeserializer<Date>() {
87+ @Override
88+ public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
89+ String value = jsonParser.getText();
90+ return Converter.parseAllDateTimeString(value);
91+ }
92+ });
93+ module.addDeserializer(Date.class, new JsonDeserializer<Date>() {
94+ @Override
95+ public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
96+ String value = jsonParser.getText();
97+ return Converter.parseAllDateTimeString(value);
98+ }
99+ });
100+ module.addDeserializer(Date.class, new JsonDeserializer<Date>() {
101+ @Override
102+ public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
103+ String value = jsonParser.getText();
104+ return Converter.parseAllDateTimeString(value);
105+ }
106+ });
107+ mapper.registerModule(module);
108+ reader = mapper.readerFor(TopLevel.class);
109+ writer = mapper.writerFor(TopLevel.class);
110+ }
111+
112+ private static ObjectReader getObjectReader() {
113+ if (reader == null) instantiateMapper();
114+ return reader;
115+ }
116+
117+ private static ObjectWriter getObjectWriter() {
118+ if (writer == null) instantiateMapper();
119+ return writer;
120+ }
121+}
Aschema-java-lombok/test/inputs/schema/transformed-string-intersection.schema/default/src/main/java/io/quicktype/TopLevel.java+12 −0
@@ -0,0 +1,12 @@
1+package io.quicktype;
2+
3+import com.fasterxml.jackson.annotation.*;
4+
5+public class TopLevel {
6+ private Committer committer;
7+
8+ @JsonProperty("committer")
9+ public Committer getCommitter() { return committer; }
10+ @JsonProperty("committer")
11+ public void setCommitter(Committer value) { this.committer = value; }
12+}
Aschema-java/test/inputs/schema/transformed-string-intersection.schema/default/src/main/java/io/quicktype/Committer.java+13 −0
@@ -0,0 +1,13 @@
1+package io.quicktype;
2+
3+import com.fasterxml.jackson.annotation.*;
4+import java.time.OffsetDateTime;
5+
6+public class Committer {
7+ private OffsetDateTime date;
8+
9+ @JsonProperty("date")
10+ public OffsetDateTime getDate() { return date; }
11+ @JsonProperty("date")
12+ public void setDate(OffsetDateTime value) { this.date = value; }
13+}
Aschema-java/test/inputs/schema/transformed-string-intersection.schema/default/src/main/java/io/quicktype/Converter.java+101 −0
@@ -0,0 +1,101 @@
1+// To use this code, add the following Maven dependency to your project:
2+//
3+//
4+// com.fasterxml.jackson.core : jackson-databind : 2.9.0
5+// com.fasterxml.jackson.datatype : jackson-datatype-jsr310 : 2.9.0
6+//
7+// Import this package:
8+//
9+// import io.quicktype.Converter;
10+//
11+// Then you can deserialize a JSON string with
12+//
13+// TopLevel data = Converter.fromJsonString(jsonString);
14+
15+package io.quicktype;
16+
17+import java.io.IOException;
18+import com.fasterxml.jackson.databind.*;
19+import com.fasterxml.jackson.databind.module.SimpleModule;
20+import com.fasterxml.jackson.core.JsonParser;
21+import com.fasterxml.jackson.core.JsonProcessingException;
22+import java.util.*;
23+import java.time.LocalDate;
24+import java.time.OffsetDateTime;
25+import java.time.OffsetTime;
26+import java.time.ZoneOffset;
27+import java.time.ZonedDateTime;
28+import java.time.format.DateTimeFormatter;
29+import java.time.format.DateTimeFormatterBuilder;
30+import java.time.temporal.ChronoField;
31+
32+public class Converter {
33+ // Date-time helpers
34+
35+ private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
36+ .appendOptional(DateTimeFormatter.ISO_DATE_TIME)
37+ .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
38+ .appendOptional(DateTimeFormatter.ISO_INSTANT)
39+ .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SX"))
40+ .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssX"))
41+ .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
42+ .toFormatter()
43+ .withZone(ZoneOffset.UTC);
44+
45+ public static OffsetDateTime parseDateTimeString(String str) {
46+ return ZonedDateTime.from(Converter.DATE_TIME_FORMATTER.parse(str)).toOffsetDateTime();
47+ }
48+
49+ private static final DateTimeFormatter TIME_FORMATTER = new DateTimeFormatterBuilder()
50+ .appendOptional(DateTimeFormatter.ISO_TIME)
51+ .appendOptional(DateTimeFormatter.ISO_OFFSET_TIME)
52+ .parseDefaulting(ChronoField.YEAR, 2020)
53+ .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
54+ .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
55+ .toFormatter()
56+ .withZone(ZoneOffset.UTC);
57+
58+ public static OffsetTime parseTimeString(String str) {
59+ return ZonedDateTime.from(Converter.TIME_FORMATTER.parse(str)).toOffsetDateTime().toOffsetTime();
60+ }
61+ // Serialize/deserialize helpers
62+
63+ public static TopLevel fromJsonString(String json) throws IOException {
64+ return getObjectReader().readValue(json);
65+ }
66+
67+ public static String toJsonString(TopLevel obj) throws JsonProcessingException {
68+ return getObjectWriter().writeValueAsString(obj);
69+ }
70+
71+ private static ObjectReader reader;
72+ private static ObjectWriter writer;
73+
74+ private static void instantiateMapper() {
75+ ObjectMapper mapper = new ObjectMapper();
76+ mapper.findAndRegisterModules();
77+ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
78+ mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
79+ SimpleModule module = new SimpleModule();
80+ module.addDeserializer(OffsetDateTime.class, new JsonDeserializer<OffsetDateTime>() {
81+ @Override
82+ public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
83+ String value = jsonParser.getText();
84+ return Converter.parseDateTimeString(value);
85+ }
86+ });
87+ mapper.registerModule(module);
88+ reader = mapper.readerFor(TopLevel.class);
89+ writer = mapper.writerFor(TopLevel.class);
90+ }
91+
92+ private static ObjectReader getObjectReader() {
93+ if (reader == null) instantiateMapper();
94+ return reader;
95+ }
96+
97+ private static ObjectWriter getObjectWriter() {
98+ if (writer == null) instantiateMapper();
99+ return writer;
100+ }
101+}
Aschema-java/test/inputs/schema/transformed-string-intersection.schema/default/src/main/java/io/quicktype/TopLevel.java+12 −0
@@ -0,0 +1,12 @@
1+package io.quicktype;
2+
3+import com.fasterxml.jackson.annotation.*;
4+
5+public class TopLevel {
6+ private Committer committer;
7+
8+ @JsonProperty("committer")
9+ public Committer getCommitter() { return committer; }
10+ @JsonProperty("committer")
11+ public void setCommitter(Committer value) { this.committer = value; }
12+}
Aschema-javascript/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.js+185 −0
@@ -0,0 +1,185 @@
1+// To parse this data:
2+//
3+// const Convert = require("./TopLevel");
4+//
5+// const topLevel = Convert.toTopLevel(json);
6+//
7+// These functions will throw an error if the JSON doesn't
8+// match the expected interface, even if the JSON is valid.
9+
10+// Converts JSON strings to/from your types
11+// and asserts the results of JSON.parse at runtime
12+function toTopLevel(json) {
13+ return cast(JSON.parse(json), r("TopLevel"));
14+}
15+
16+function topLevelToJson(value) {
17+ return JSON.stringify(uncast(value, r("TopLevel")), null, 2);
18+}
19+
20+function invalidValue(typ, val, key, parent = '') {
21+ const prettyTyp = prettyTypeName(typ);
22+ const parentText = parent ? ` on ${parent}` : '';
23+ const keyText = key ? ` for key "${key}"` : '';
24+ throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`);
25+}
26+
27+function prettyTypeName(typ) {
28+ if (Array.isArray(typ)) {
29+ if (typ.length === 2 && typ[0] === undefined) {
30+ return `an optional ${prettyTypeName(typ[1])}`;
31+ } else {
32+ return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`;
33+ }
34+ } else if (typeof typ === "object" && typ.literal !== undefined) {
35+ return typ.literal;
36+ } else {
37+ return typeof typ;
38+ }
39+}
40+
41+function jsonToJSProps(typ) {
42+ if (typ.jsonToJS === undefined) {
43+ const map = {};
44+ typ.props.forEach((p) => map[p.json] = { key: p.js, typ: p.typ });
45+ typ.jsonToJS = map;
46+ }
47+ return typ.jsonToJS;
48+}
49+
50+function jsToJSONProps(typ) {
51+ if (typ.jsToJSON === undefined) {
52+ const map = {};
53+ typ.props.forEach((p) => map[p.js] = { key: p.json, typ: p.typ });
54+ typ.jsToJSON = map;
55+ }
56+ return typ.jsToJSON;
57+}
58+
59+function transform(val, typ, getProps, key = '', parent = '') {
60+ function transformPrimitive(typ, val) {
61+ if (typeof typ === typeof val) return val;
62+ return invalidValue(typ, val, key, parent);
63+ }
64+
65+ function transformUnion(typs, val) {
66+ // val must validate against one typ in typs
67+ const l = typs.length;
68+ for (let i = 0; i < l; i++) {
69+ const typ = typs[i];
70+ try {
71+ return transform(val, typ, getProps);
72+ } catch (_) {}
73+ }
74+ return invalidValue(typs, val, key, parent);
75+ }
76+
77+ function transformEnum(cases, val) {
78+ if (cases.indexOf(val) !== -1) return val;
79+ return invalidValue(cases.map(a => { return l(a); }), val, key, parent);
80+ }
81+
82+ function transformArray(typ, val) {
83+ // val must be an array with no invalid elements
84+ if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent);
85+ return val.map(el => transform(el, typ, getProps));
86+ }
87+
88+ function transformDate(val) {
89+ if (val === null) {
90+ return null;
91+ }
92+ const d = new Date(val);
93+ if (isNaN(d.valueOf())) {
94+ return invalidValue(l("Date"), val, key, parent);
95+ }
96+ return d;
97+ }
98+
99+ function transformObject(props, additional, val) {
100+ if (val === null || typeof val !== "object" || Array.isArray(val)) {
101+ return invalidValue(l(ref || "object"), val, key, parent);
102+ }
103+ const result = {};
104+ Object.getOwnPropertyNames(props).forEach(key => {
105+ const prop = props[key];
106+ const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined;
107+ result[prop.key] = transform(v, prop.typ, getProps, key, ref);
108+ });
109+ Object.getOwnPropertyNames(val).forEach(key => {
110+ if (!Object.prototype.hasOwnProperty.call(props, key)) {
111+ result[key] = transform(val[key], additional, getProps, key, ref);
112+ }
113+ });
114+ return result;
115+ }
116+
117+ if (typ === "any") return val;
118+ if (typ === null) {
119+ if (val === null) return val;
120+ return invalidValue(typ, val, key, parent);
121+ }
122+ if (typ === false) return invalidValue(typ, val, key, parent);
123+ let ref = undefined;
124+ while (typeof typ === "object" && typ.ref !== undefined) {
125+ ref = typ.ref;
126+ typ = typeMap[typ.ref];
127+ }
128+ if (Array.isArray(typ)) return transformEnum(typ, val);
129+ if (typeof typ === "object") {
130+ return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val)
131+ : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val)
132+ : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val)
133+ : invalidValue(typ, val, key, parent);
134+ }
135+ // Numbers can be parsed by Date but shouldn't be.
136+ if (typ === Date && typeof val !== "number") return transformDate(val);
137+ return transformPrimitive(typ, val);
138+}
139+
140+function cast(val, typ) {
141+ return transform(val, typ, jsonToJSProps);
142+}
143+
144+function uncast(val, typ) {
145+ return transform(val, typ, jsToJSONProps);
146+}
147+
148+function l(typ) {
149+ return { literal: typ };
150+}
151+
152+function a(typ) {
153+ return { arrayItems: typ };
154+}
155+
156+function u(...typs) {
157+ return { unionMembers: typs };
158+}
159+
160+function o(props, additional) {
161+ return { props, additional };
162+}
163+
164+function m(additional) {
165+ const props = [];
166+ return { props, additional };
167+}
168+
169+function r(name) {
170+ return { ref: name };
171+}
172+
173+const typeMap = {
174+ "TopLevel": o([
175+ { json: "committer", js: "committer", typ: r("Committer") },
176+ ], "any"),
177+ "Committer": o([
178+ { json: "date", js: "date", typ: Date },
179+ ], "any"),
180+};
181+
182+module.exports = {
183+ "topLevelToJson": topLevelToJson,
184+ "toTopLevel": toTopLevel,
185+};
Aschema-kotlin-jackson/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.kt+34 −0
@@ -0,0 +1,34 @@
1+// To parse the JSON, install Klaxon and do:
2+//
3+// val topLevel = TopLevel.fromJson(jsonString)
4+
5+package quicktype
6+
7+import java.time.OffsetDateTime
8+
9+import com.beust.klaxon.*
10+
11+private fun <T> Klaxon.convert(k: kotlin.reflect.KClass<*>, fromJson: (JsonValue) -> T, toJson: (T) -> String, isUnion: Boolean = false) =
12+ this.converter(object: Converter {
13+ @Suppress("UNCHECKED_CAST")
14+ override fun toJson(value: Any) = toJson(value as T)
15+ override fun fromJson(jv: JsonValue) = fromJson(jv) as Any
16+ override fun canConvert(cls: Class<*>) = cls == k.java || (isUnion && cls.superclass == k.java)
17+ })
18+
19+private val klaxon = Klaxon()
20+ .convert(OffsetDateTime::class, { OffsetDateTime.parse(it.string!!) }, { "\"${java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(it)}\"" })
21+
22+data class TopLevel (
23+ val committer: Committer
24+) {
25+ public fun toJson() = klaxon.toJsonString(this)
26+
27+ companion object {
28+ public fun fromJson(json: String) = klaxon.parse<TopLevel>(json)
29+ }
30+}
31+
32+data class Committer (
33+ val date: OffsetDateTime
34+)
Aschema-kotlin/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.kt+49 −0
@@ -0,0 +1,49 @@
1+// To parse the JSON, install jackson-module-kotlin and do:
2+//
3+// val topLevel = TopLevel.fromJson(jsonString)
4+
5+package quicktype
6+
7+import java.time.OffsetDateTime
8+
9+import com.fasterxml.jackson.annotation.*
10+import com.fasterxml.jackson.core.*
11+import com.fasterxml.jackson.databind.*
12+import com.fasterxml.jackson.databind.deser.std.StdDeserializer
13+import com.fasterxml.jackson.databind.module.SimpleModule
14+import com.fasterxml.jackson.databind.node.*
15+import com.fasterxml.jackson.databind.ser.std.StdSerializer
16+import com.fasterxml.jackson.module.kotlin.*
17+
18+
19+@Suppress("UNCHECKED_CAST")
20+private fun <T> ObjectMapper.convert(k: kotlin.reflect.KClass<*>, fromJson: (JsonNode) -> T, toJson: (T) -> String, isUnion: Boolean = false) = registerModule(SimpleModule().apply {
21+ addSerializer(k.java as Class<T>, object : StdSerializer<T>(k.java as Class<T>) {
22+ override fun serialize(value: T, gen: JsonGenerator, provider: SerializerProvider) = gen.writeRawValue(toJson(value))
23+ })
24+ addDeserializer(k.java as Class<T>, object : StdDeserializer<T>(k.java as Class<T>) {
25+ override fun deserialize(p: JsonParser, ctxt: DeserializationContext) = fromJson(p.readValueAsTree())
26+ })
27+})
28+
29+val mapper = jacksonObjectMapper().apply {
30+ propertyNamingStrategy = PropertyNamingStrategy.LOWER_CAMEL_CASE
31+ setSerializationInclusion(JsonInclude.Include.NON_NULL)
32+ convert(OffsetDateTime::class, { OffsetDateTime.parse(it.asText()) }, { "\"${java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(it)}\"" })
33+}
34+
35+data class TopLevel (
36+ @get:JsonProperty(required=true)@field:JsonProperty(required=true)
37+ val committer: Committer
38+) {
39+ fun toJson() = mapper.writeValueAsString(this)
40+
41+ companion object {
42+ fun fromJson(json: String) = mapper.readValue<TopLevel>(json)
43+ }
44+}
45+
46+data class Committer (
47+ @get:JsonProperty(required=true)@field:JsonProperty(required=true)
48+ val date: OffsetDateTime
49+)
Aschema-kotlinx/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.kt+33 −0
@@ -0,0 +1,33 @@
1+// To parse the JSON, install kotlin's serialization plugin and do:
2+//
3+// val json = Json { allowStructuredMapKeys = true }
4+// val topLevel = json.parse(TopLevel.serializer(), jsonString)
5+
6+@file:UseSerializers(OffsetDateTimeSerializer::class)
7+
8+package quicktype
9+
10+import java.time.OffsetDateTime
11+
12+import kotlinx.serialization.*
13+import kotlinx.serialization.json.*
14+import kotlinx.serialization.descriptors.*
15+import kotlinx.serialization.encoding.*
16+
17+@Serializable
18+data class TopLevel (
19+ val committer: Committer
20+)
21+
22+@Serializable
23+data class Committer (
24+ val date: OffsetDateTime
25+)
26+
27+object OffsetDateTimeSerializer : KSerializer<OffsetDateTime> {
28+ override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("OffsetDateTime", PrimitiveKind.STRING)
29+ override fun deserialize(decoder: Decoder): OffsetDateTime = OffsetDateTime.parse(decoder.decodeString())
30+ override fun serialize(encoder: Encoder, value: OffsetDateTime) {
31+ encoder.encodeString(java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value))
32+ }
33+}
Aschema-php/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.php+206 −0
@@ -0,0 +1,206 @@
1+<?php
2+declare(strict_types=1);
3+
4+// This is an autogenerated file:TopLevel
5+
6+class TopLevel {
7+ private Committer $committer; // json:committer Required
8+
9+ /**
10+ * @param Committer $committer
11+ */
12+ public function __construct(Committer $committer) {
13+ $this->committer = $committer;
14+ }
15+
16+ /**
17+ * @param stdClass $value
18+ * @throws Exception
19+ * @return Committer
20+ */
21+ public static function fromCommitter(stdClass $value): Committer {
22+ return Committer::from($value); /*class*/
23+ }
24+
25+ /**
26+ * @throws Exception
27+ * @return stdClass
28+ */
29+ public function toCommitter(): stdClass {
30+ if (TopLevel::validateCommitter($this->committer)) {
31+ return $this->committer->to(); /*class*/
32+ }
33+ throw new Exception('never get to this TopLevel::committer');
34+ }
35+
36+ /**
37+ * @param Committer
38+ * @return bool
39+ * @throws Exception
40+ */
41+ public static function validateCommitter(Committer $value): bool {
42+ $value->validate();
43+ return true;
44+ }
45+
46+ /**
47+ * @throws Exception
48+ * @return Committer
49+ */
50+ public function getCommitter(): Committer {
51+ if (TopLevel::validateCommitter($this->committer)) {
52+ return $this->committer;
53+ }
54+ throw new Exception('never get to getCommitter TopLevel::committer');
55+ }
56+
57+ /**
58+ * @return Committer
59+ */
60+ public static function sampleCommitter(): Committer {
61+ return Committer::sample(); /*31:committer*/
62+ }
63+
64+ /**
65+ * @throws Exception
66+ * @return bool
67+ */
68+ public function validate(): bool {
69+ return TopLevel::validateCommitter($this->committer);
70+ }
71+
72+ /**
73+ * @return stdClass
74+ * @throws Exception
75+ */
76+ public function to(): stdClass {
77+ $out = new stdClass();
78+ $out->{'committer'} = $this->toCommitter();
79+ return $out;
80+ }
81+
82+ /**
83+ * @param stdClass $obj
84+ * @return TopLevel
85+ * @throws Exception
86+ */
87+ public static function from(stdClass $obj): TopLevel {
88+ return new TopLevel(
89+ TopLevel::fromCommitter($obj->{'committer'})
90+ );
91+ }
92+
93+ /**
94+ * @return TopLevel
95+ */
96+ public static function sample(): TopLevel {
97+ return new TopLevel(
98+ TopLevel::sampleCommitter()
99+ );
100+ }
101+}
102+
103+// This is an autogenerated file:Committer
104+
105+class Committer {
106+ private DateTime $date; // json:date Required
107+
108+ /**
109+ * @param DateTime $date
110+ */
111+ public function __construct(DateTime $date) {
112+ $this->date = $date;
113+ }
114+
115+ /**
116+ * @param string $value
117+ * @throws Exception
118+ * @return DateTime
119+ */
120+ public static function fromDate(string $value): DateTime {
121+ $tmp = DateTime::createFromFormat(DateTimeInterface::ISO8601, $value);
122+ if (!is_a($tmp, 'DateTime')) {
123+ throw new Exception('Attribute Error:Committer::');
124+ }
125+ return $tmp;
126+ }
127+
128+ /**
129+ * @throws Exception
130+ * @return string
131+ */
132+ public function toDate(): string {
133+ if (Committer::validateDate($this->date)) {
134+ return $this->date->format(DateTimeInterface::ISO8601);
135+ }
136+ throw new Exception('never get to this Committer::date');
137+ }
138+
139+ /**
140+ * @param DateTime
141+ * @return bool
142+ * @throws Exception
143+ */
144+ public static function validateDate(DateTime $value): bool {
145+ if (!is_a($value, 'DateTime')) {
146+ throw new Exception('Attribute Error:Committer::date');
147+ }
148+ return true;
149+ }
150+
151+ /**
152+ * @throws Exception
153+ * @return DateTime
154+ */
155+ public function getDate(): DateTime {
156+ if (Committer::validateDate($this->date)) {
157+ return $this->date;
158+ }
159+ throw new Exception('never get to getDate Committer::date');
160+ }
161+
162+ /**
163+ * @return DateTime
164+ */
165+ public static function sampleDate(): DateTime {
166+ return DateTime::createFromFormat(DateTimeInterface::ISO8601, '2020-12-10T12:10:10+00:00');
167+ }
168+
169+ /**
170+ * @throws Exception
171+ * @return bool
172+ */
173+ public function validate(): bool {
174+ return Committer::validateDate($this->date);
175+ }
176+
177+ /**
178+ * @return stdClass
179+ * @throws Exception
180+ */
181+ public function to(): stdClass {
182+ $out = new stdClass();
183+ $out->{'date'} = $this->toDate();
184+ return $out;
185+ }
186+
187+ /**
188+ * @param stdClass $obj
189+ * @return Committer
190+ * @throws Exception
191+ */
192+ public static function from(stdClass $obj): Committer {
193+ return new Committer(
194+ Committer::fromDate($obj->{'date'})
195+ );
196+ }
197+
198+ /**
199+ * @return Committer
200+ */
201+ public static function sample(): Committer {
202+ return new Committer(
203+ Committer::sampleDate()
204+ );
205+ }
206+}
Aschema-pike/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.pmod+53 −0
@@ -0,0 +1,53 @@
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+ Committer committer; // json: "committer"
17+
18+ string encode_json() {
19+ mapping(string:mixed) json = ([
20+ "committer" : committer,
21+ ]);
22+
23+ return Standards.JSON.encode(json);
24+ }
25+}
26+
27+TopLevel TopLevel_from_JSON(mixed json) {
28+ TopLevel retval = TopLevel();
29+
30+ retval.committer = json["committer"];
31+
32+ return retval;
33+}
34+
35+class Committer {
36+ string date; // json: "date"
37+
38+ string encode_json() {
39+ mapping(string:mixed) json = ([
40+ "date" : date,
41+ ]);
42+
43+ return Standards.JSON.encode(json);
44+ }
45+}
46+
47+Committer Committer_from_JSON(mixed json) {
48+ Committer retval = Committer();
49+
50+ retval.date = json["date"];
51+
52+ return retval;
53+}
Aschema-python/test/inputs/schema/transformed-string-intersection.schema/default/quicktype.py+56 −0
@@ -0,0 +1,56 @@
1+import datetime
2+from dataclasses import dataclass
3+from typing import Any, TypeVar, Type, cast
4+import dateutil.parser
5+
6+
7+T = TypeVar("T")
8+
9+
10+def from_datetime(x: Any) -> datetime.datetime:
11+ return dateutil.parser.parse(x)
12+
13+
14+def to_class(c: Type[T], x: Any) -> dict:
15+ assert isinstance(x, c)
16+ return cast(Any, x).to_dict()
17+
18+
19+@dataclass
20+class Committer:
21+ date: datetime.datetime
22+
23+ @staticmethod
24+ def from_dict(obj: Any) -> 'Committer':
25+ assert isinstance(obj, dict)
26+ date = from_datetime(obj.get("date"))
27+ return Committer(date)
28+
29+ def to_dict(self) -> dict:
30+ result: dict = {}
31+ result["date"] = self.date.isoformat()
32+ return result
33+
34+
35+@dataclass
36+class TopLevel:
37+ committer: Committer
38+
39+ @staticmethod
40+ def from_dict(obj: Any) -> 'TopLevel':
41+ assert isinstance(obj, dict)
42+ committer = Committer.from_dict(obj.get("committer"))
43+ return TopLevel(committer)
44+
45+ def to_dict(self) -> dict:
46+ result: dict = {}
47+ result["committer"] = to_class(Committer, self.committer)
48+ return result
49+
50+
51+def top_level_from_dict(s: Any) -> TopLevel:
52+ return TopLevel.from_dict(s)
53+
54+
55+def top_level_to_dict(x: TopLevel) -> Any:
56+ return to_class(TopLevel, x)
Aschema-ruby/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.rb+70 −0
@@ -0,0 +1,70 @@
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+# top_level = TopLevel.from_json! "{…}"
7+# puts top_level.committer.date
8+#
9+# If from_json! succeeds, the value returned matches the schema.
10+
11+require 'json'
12+require 'dry-types'
13+require 'dry-struct'
14+
15+module Types
16+ include Dry.Types(default: :nominal)
17+
18+ Hash = Strict::Hash
19+ String = Strict::String
20+end
21+
22+class Committer < Dry::Struct
23+ attribute :date, Types::String
24+
25+ def self.from_dynamic!(d)
26+ d = Types::Hash[d]
27+ new(
28+ date: d.fetch("date"),
29+ )
30+ end
31+
32+ def self.from_json!(json)
33+ from_dynamic!(JSON.parse(json))
34+ end
35+
36+ def to_dynamic
37+ {
38+ "date" => date,
39+ }
40+ end
41+
42+ def to_json(options = nil)
43+ JSON.generate(to_dynamic, options)
44+ end
45+end
46+
47+class TopLevel < Dry::Struct
48+ attribute :committer, Committer
49+
50+ def self.from_dynamic!(d)
51+ d = Types::Hash[d]
52+ new(
53+ committer: Committer.from_dynamic!(d.fetch("committer")),
54+ )
55+ end
56+
57+ def self.from_json!(json)
58+ from_dynamic!(JSON.parse(json))
59+ end
60+
61+ def to_dynamic
62+ {
63+ "committer" => committer.to_dynamic,
64+ }
65+ end
66+
67+ def to_json(options = nil)
68+ JSON.generate(to_dynamic, options)
69+ end
70+end
Aschema-rust/test/inputs/schema/transformed-string-intersection.schema/default/module_under_test.rs+24 −0
@@ -0,0 +1,24 @@
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::TopLevel;
8+//
9+// fn main() {
10+// let json = r#"{"answer": 42}"#;
11+// let model: TopLevel = 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 committer: Committer,
19+}
20+
21+#[derive(Debug, Clone, Serialize, Deserialize)]
22+pub struct Committer {
23+ pub date: String,
24+}
Aschema-scala3-upickle/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.scala+16 −0
@@ -0,0 +1,16 @@
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 committer : Committer
12+) derives Encoder.AsObject, Decoder
13+
14+case class Committer (
15+ val date : String
16+) derives Encoder.AsObject, Decoder
Aschema-scala3/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.scala+74 −0
@@ -0,0 +1,74 @@
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 committer : Committer
70+) derives OptionPickler.ReadWriter
71+
72+case class Committer (
73+ val date : String
74+) derives OptionPickler.ReadWriter
Aschema-schema/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.schema+33 −0
@@ -0,0 +1,33 @@
1+{
2+ "$schema": "http://json-schema.org/draft-06/schema#",
3+ "$ref": "#/definitions/TopLevel",
4+ "definitions": {
5+ "TopLevel": {
6+ "type": "object",
7+ "additionalProperties": {},
8+ "properties": {
9+ "committer": {
10+ "$ref": "#/definitions/Committer"
11+ }
12+ },
13+ "required": [
14+ "committer"
15+ ],
16+ "title": "TopLevel"
17+ },
18+ "Committer": {
19+ "type": "object",
20+ "additionalProperties": {},
21+ "properties": {
22+ "date": {
23+ "type": "string",
24+ "format": "date-time"
25+ }
26+ },
27+ "required": [
28+ "date"
29+ ],
30+ "title": "Committer"
31+ }
32+ }
33+}
Aschema-swift/test/inputs/schema/transformed-string-intersection.schema/default/quicktype.swift+130 −0
@@ -0,0 +1,130 @@
1+// This file was generated from JSON Schema using quicktype, do not modify it directly.
2+// To parse the JSON, add this file to your project and do:
3+//
4+// let topLevel = try TopLevel(json)
5+
6+import Foundation
7+
8+// MARK: - TopLevel
9+struct TopLevel: Codable {
10+ let committer: Committer
11+
12+ enum CodingKeys: String, CodingKey {
13+ case committer = "committer"
14+ }
15+}
16+
17+// MARK: TopLevel convenience initializers and mutators
18+
19+extension TopLevel {
20+ init(data: Data) throws {
21+ self = try newJSONDecoder().decode(TopLevel.self, from: data)
22+ }
23+
24+ init(_ json: String, using encoding: String.Encoding = .utf8) throws {
25+ guard let data = json.data(using: encoding) else {
26+ throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
27+ }
28+ try self.init(data: data)
29+ }
30+
31+ init(fromURL url: URL) throws {
32+ try self.init(data: try Data(contentsOf: url))
33+ }
34+
35+ func with(
36+ committer: Committer? = nil
37+ ) -> TopLevel {
38+ return TopLevel(
39+ committer: committer ?? self.committer
40+ )
41+ }
42+
43+ func jsonData() throws -> Data {
44+ return try newJSONEncoder().encode(self)
45+ }
46+
47+ func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
48+ return String(data: try self.jsonData(), encoding: encoding)
49+ }
50+}
51+
52+// MARK: - Committer
53+struct Committer: Codable {
54+ let date: Date
55+
56+ enum CodingKeys: String, CodingKey {
57+ case date = "date"
58+ }
59+}
60+
61+// MARK: Committer convenience initializers and mutators
62+
63+extension Committer {
64+ init(data: Data) throws {
65+ self = try newJSONDecoder().decode(Committer.self, from: data)
66+ }
67+
68+ init(_ json: String, using encoding: String.Encoding = .utf8) throws {
69+ guard let data = json.data(using: encoding) else {
70+ throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
71+ }
72+ try self.init(data: data)
73+ }
74+
75+ init(fromURL url: URL) throws {
76+ try self.init(data: try Data(contentsOf: url))
77+ }
78+
79+ func with(
80+ date: Date? = nil
81+ ) -> Committer {
82+ return Committer(
83+ date: date ?? self.date
84+ )
85+ }
86+
87+ func jsonData() throws -> Data {
88+ return try newJSONEncoder().encode(self)
89+ }
90+
91+ func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
92+ return String(data: try self.jsonData(), encoding: encoding)
93+ }
94+}
95+
96+// MARK: - Helper functions for creating encoders and decoders
97+
98+func newJSONDecoder() -> JSONDecoder {
99+ let decoder = JSONDecoder()
100+ decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in
101+ let container = try decoder.singleValueContainer()
102+ let dateStr = try container.decode(String.self)
103+
104+ let formatter = DateFormatter()
105+ formatter.calendar = Calendar(identifier: .iso8601)
106+ formatter.locale = Locale(identifier: "en_US_POSIX")
107+ formatter.timeZone = TimeZone(secondsFromGMT: 0)
108+ formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
109+ if let date = formatter.date(from: dateStr) {
110+ return date
111+ }
112+ formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXXXX"
113+ if let date = formatter.date(from: dateStr) {
114+ return date
115+ }
116+ throw DecodingError.typeMismatch(Date.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Could not decode date"))
117+ })
118+ return decoder
119+}
120+
121+func newJSONEncoder() -> JSONEncoder {
122+ let encoder = JSONEncoder()
123+ let formatter = DateFormatter()
124+ formatter.calendar = Calendar(identifier: .iso8601)
125+ formatter.locale = Locale(identifier: "en_US_POSIX")
126+ formatter.timeZone = TimeZone(secondsFromGMT: 0)
127+ formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXXXX"
128+ encoder.dateEncodingStrategy = .formatted(formatter)
129+ return encoder
130+}
Aschema-typescript-zod/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.ts+192 −0
@@ -0,0 +1,192 @@
1+// To parse this data:
2+//
3+// import { Convert, TopLevel } from "./TopLevel";
4+//
5+// const topLevel = Convert.toTopLevel(json);
6+//
7+// These functions will throw an error if the JSON doesn't
8+// match the expected interface, even if the JSON is valid.
9+
10+export interface TopLevel {
11+ committer: Committer;
12+ [property: string]: unknown;
13+}
14+
15+export interface Committer {
16+ date: Date;
17+ [property: string]: unknown;
18+}
19+
20+// Converts JSON strings to/from your types
21+// and asserts the results of JSON.parse at runtime
22+export class Convert {
23+ public static toTopLevel(json: string): TopLevel {
24+ return cast(JSON.parse(json), r("TopLevel"));
25+ }
26+
27+ public static topLevelToJson(value: TopLevel): string {
28+ return JSON.stringify(uncast(value, r("TopLevel")), null, 2);
29+ }
30+}
31+
32+function invalidValue(typ: any, val: any, key: any, parent: any = ''): never {
33+ const prettyTyp = prettyTypeName(typ);
34+ const parentText = parent ? ` on ${parent}` : '';
35+ const keyText = key ? ` for key "${key}"` : '';
36+ throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`);
37+}
38+
39+function prettyTypeName(typ: any): string {
40+ if (Array.isArray(typ)) {
41+ if (typ.length === 2 && typ[0] === undefined) {
42+ return `an optional ${prettyTypeName(typ[1])}`;
43+ } else {
44+ return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`;
45+ }
46+ } else if (typeof typ === "object" && typ.literal !== undefined) {
47+ return typ.literal;
48+ } else {
49+ return typeof typ;
50+ }
51+}
52+
53+function jsonToJSProps(typ: any): any {
54+ if (typ.jsonToJS === undefined) {
55+ const map: any = {};
56+ typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ });
57+ typ.jsonToJS = map;
58+ }
59+ return typ.jsonToJS;
60+}
61+
62+function jsToJSONProps(typ: any): any {
63+ if (typ.jsToJSON === undefined) {
64+ const map: any = {};
65+ typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ });
66+ typ.jsToJSON = map;
67+ }
68+ return typ.jsToJSON;
69+}
70+
71+function transform(val: any, typ: any, getProps: any, key: any = '', parent: any = ''): any {
72+ function transformPrimitive(typ: string, val: any): any {
73+ if (typeof typ === typeof val) return val;
74+ return invalidValue(typ, val, key, parent);
75+ }
76+
77+ function transformUnion(typs: any[], val: any): any {
78+ // val must validate against one typ in typs
79+ const l = typs.length;
80+ for (let i = 0; i < l; i++) {
81+ const typ = typs[i];
82+ try {
83+ return transform(val, typ, getProps);
84+ } catch (_) {}
85+ }
86+ return invalidValue(typs, val, key, parent);
87+ }
88+
89+ function transformEnum(cases: string[], val: any): any {
90+ if (cases.indexOf(val) !== -1) return val;
91+ return invalidValue(cases.map(a => { return l(a); }), val, key, parent);
92+ }
93+
94+ function transformArray(typ: any, val: any): any {
95+ // val must be an array with no invalid elements
96+ if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent);
97+ return val.map(el => transform(el, typ, getProps));
98+ }
99+
100+ function transformDate(val: any): any {
101+ if (val === null) {
102+ return null;
103+ }
104+ const d = new Date(val);
105+ if (isNaN(d.valueOf())) {
106+ return invalidValue(l("Date"), val, key, parent);
107+ }
108+ return d;
109+ }
110+
111+ function transformObject(props: { [k: string]: any }, additional: any, val: any): any {
112+ if (val === null || typeof val !== "object" || Array.isArray(val)) {
113+ return invalidValue(l(ref || "object"), val, key, parent);
114+ }
115+ const result: any = {};
116+ Object.getOwnPropertyNames(props).forEach(key => {
117+ const prop = props[key];
118+ const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined;
119+ result[prop.key] = transform(v, prop.typ, getProps, key, ref);
120+ });
121+ Object.getOwnPropertyNames(val).forEach(key => {
122+ if (!Object.prototype.hasOwnProperty.call(props, key)) {
123+ result[key] = transform(val[key], additional, getProps, key, ref);
124+ }
125+ });
126+ return result;
127+ }
128+
129+ if (typ === "any") return val;
130+ if (typ === null) {
131+ if (val === null) return val;
132+ return invalidValue(typ, val, key, parent);
133+ }
134+ if (typ === false) return invalidValue(typ, val, key, parent);
135+ let ref: any = undefined;
136+ while (typeof typ === "object" && typ.ref !== undefined) {
137+ ref = typ.ref;
138+ typ = typeMap[typ.ref];
139+ }
140+ if (Array.isArray(typ)) return transformEnum(typ, val);
141+ if (typeof typ === "object") {
142+ return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val)
143+ : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val)
144+ : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val)
145+ : invalidValue(typ, val, key, parent);
146+ }
147+ // Numbers can be parsed by Date but shouldn't be.
148+ if (typ === Date && typeof val !== "number") return transformDate(val);
149+ return transformPrimitive(typ, val);
150+}
151+
152+function cast<T>(val: any, typ: any): T {
153+ return transform(val, typ, jsonToJSProps);
154+}
155+
156+function uncast<T>(val: T, typ: any): any {
157+ return transform(val, typ, jsToJSONProps);
158+}
159+
160+function l(typ: any) {
161+ return { literal: typ };
162+}
163+
164+function a(typ: any) {
165+ return { arrayItems: typ };
166+}
167+
168+function u(...typs: any[]) {
169+ return { unionMembers: typs };
170+}
171+
172+function o(props: any[], additional: any) {
173+ return { props, additional };
174+}
175+
176+function m(additional: any) {
177+ const props: any[] = [];
178+ return { props, additional };
179+}
180+
181+function r(name: string) {
182+ return { ref: name };
183+}
184+
185+const typeMap: any = {
186+ "TopLevel": o([
187+ { json: "committer", js: "committer", typ: r("Committer") },
188+ ], "any"),
189+ "Committer": o([
190+ { json: "date", js: "date", typ: Date },
191+ ], "any"),
192+};
Aschema-typescript/test/inputs/schema/transformed-string-intersection.schema/default/TopLevel.ts+12 −0
@@ -0,0 +1,12 @@
1+import * as z from "zod";
2+
3+
4+export const CommitterSchema = z.object({
5+ "date": z.coerce.date(),
6+});
7+export type Committer = z.infer<typeof CommitterSchema>;
8+
9+export const TopLevelSchema = z.object({
10+ "committer": CommitterSchema,
11+});
12+export type TopLevel = z.infer<typeof TopLevelSchema>;
No generated files match these filters.