quicktype-core 6.1.11 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +0 -3
- package/dist/language/All.js +1 -1
- package/dist/language/CSharp.d.ts +67 -8
- package/dist/language/CSharp.js +785 -24
- package/dist/language/Rust.js +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export { removeNullFromUnion, matchType, nullableFromUnion } from "./TypeUtils";
|
|
|
29
29
|
export { ConvenienceRenderer } from "./ConvenienceRenderer";
|
|
30
30
|
export { uriTypeAttributeKind } from "./attributes/URIAttributes";
|
|
31
31
|
export { CPlusPlusTargetLanguage, CPlusPlusRenderer, cPlusPlusOptions } from "./language/CPlusPlus";
|
|
32
|
-
export { CSharpTargetLanguage, cSharpOptions, CSharpRenderer
|
|
32
|
+
export { CSharpTargetLanguage, cSharpOptions, CSharpRenderer } from "./language/CSharp";
|
|
33
33
|
export { GoTargetLanguage, GoRenderer, goOptions } from "./language/Golang";
|
|
34
34
|
export { ObjectiveCTargetLanguage, ObjectiveCRenderer, objcOptions } from "./language/Objective-C";
|
|
35
35
|
export { JavaTargetLanguage, JavaRenderer, javaOptions } from "./language/Java";
|
package/dist/index.js
CHANGED
|
@@ -111,9 +111,6 @@ var CSharp_1 = require("./language/CSharp");
|
|
|
111
111
|
exports.CSharpTargetLanguage = CSharp_1.CSharpTargetLanguage;
|
|
112
112
|
exports.cSharpOptions = CSharp_1.cSharpOptions;
|
|
113
113
|
exports.CSharpRenderer = CSharp_1.CSharpRenderer;
|
|
114
|
-
exports.NewtonsoftCSharpTargetLanguage = CSharp_1.NewtonsoftCSharpTargetLanguage;
|
|
115
|
-
exports.newtonsoftCSharpOptions = CSharp_1.newtonsoftCSharpOptions;
|
|
116
|
-
exports.NewtonsoftCSharpRenderer = CSharp_1.NewtonsoftCSharpRenderer;
|
|
117
114
|
var Golang_1 = require("./language/Golang");
|
|
118
115
|
exports.GoTargetLanguage = Golang_1.GoTargetLanguage;
|
|
119
116
|
exports.GoRenderer = Golang_1.GoRenderer;
|
package/dist/language/All.js
CHANGED
|
@@ -21,7 +21,7 @@ const Python_1 = require("./Python");
|
|
|
21
21
|
const Pike_1 = require("./Pike");
|
|
22
22
|
const Haskell_1 = require("./Haskell");
|
|
23
23
|
exports.all = [
|
|
24
|
-
new CSharp_1.
|
|
24
|
+
new CSharp_1.CSharpTargetLanguage(),
|
|
25
25
|
new Golang_1.GoTargetLanguage(),
|
|
26
26
|
new Rust_1.RustTargetLanguage(),
|
|
27
27
|
new Crystal_1.CrystalTargetLanguage(),
|
|
@@ -7,6 +7,10 @@ import { StringOption, EnumOption, Option, BooleanOption, OptionValues } from ".
|
|
|
7
7
|
import { StringTypeMapping } from "../TypeBuilder";
|
|
8
8
|
import { Transformation } from "../Transformers";
|
|
9
9
|
import { RenderContext } from "../Renderer";
|
|
10
|
+
export declare enum Framework {
|
|
11
|
+
Newtonsoft = 0,
|
|
12
|
+
SystemTextJson = 1
|
|
13
|
+
}
|
|
10
14
|
export declare type Version = 5 | 6;
|
|
11
15
|
export declare type OutputFeatures = {
|
|
12
16
|
helpers: boolean;
|
|
@@ -19,6 +23,7 @@ export declare enum AccessModifier {
|
|
|
19
23
|
}
|
|
20
24
|
export declare type CSharpTypeForAny = "object" | "dynamic";
|
|
21
25
|
export declare const cSharpOptions: {
|
|
26
|
+
framework: EnumOption<Framework>;
|
|
22
27
|
useList: EnumOption<boolean>;
|
|
23
28
|
dense: EnumOption<boolean>;
|
|
24
29
|
namespace: StringOption;
|
|
@@ -28,6 +33,7 @@ export declare const cSharpOptions: {
|
|
|
28
33
|
useDecimal: EnumOption<boolean>;
|
|
29
34
|
};
|
|
30
35
|
export declare class CSharpTargetLanguage extends TargetLanguage {
|
|
36
|
+
constructor();
|
|
31
37
|
protected getOptions(): Option<any>[];
|
|
32
38
|
readonly stringTypeMapping: StringTypeMapping;
|
|
33
39
|
readonly supportsUnionsWithBothNumberTypes: boolean;
|
|
@@ -35,7 +41,7 @@ export declare class CSharpTargetLanguage extends TargetLanguage {
|
|
|
35
41
|
needsTransformerForType(t: Type): boolean;
|
|
36
42
|
protected makeRenderer(renderContext: RenderContext, untypedOptionValues: {
|
|
37
43
|
[name: string]: any;
|
|
38
|
-
}):
|
|
44
|
+
}): ConvenienceRenderer;
|
|
39
45
|
}
|
|
40
46
|
export declare class CSharpRenderer extends ConvenienceRenderer {
|
|
41
47
|
private readonly _csOptions;
|
|
@@ -69,10 +75,12 @@ export declare class CSharpRenderer extends ConvenienceRenderer {
|
|
|
69
75
|
protected emitRequiredHelpers(): void;
|
|
70
76
|
private emitTypesAndSupport;
|
|
71
77
|
protected emitDefaultLeadingComments(): void;
|
|
78
|
+
protected emitDefaultFollowingComments(): void;
|
|
72
79
|
protected needNamespace(): boolean;
|
|
73
80
|
protected emitSourceStructure(): void;
|
|
74
81
|
}
|
|
75
82
|
export declare const newtonsoftCSharpOptions: {
|
|
83
|
+
framework: EnumOption<Framework>;
|
|
76
84
|
useList: EnumOption<boolean>;
|
|
77
85
|
dense: EnumOption<boolean>;
|
|
78
86
|
namespace: StringOption;
|
|
@@ -89,13 +97,6 @@ export declare const newtonsoftCSharpOptions: {
|
|
|
89
97
|
baseclass: EnumOption<string | undefined>;
|
|
90
98
|
checkRequired: BooleanOption;
|
|
91
99
|
};
|
|
92
|
-
export declare class NewtonsoftCSharpTargetLanguage extends CSharpTargetLanguage {
|
|
93
|
-
constructor();
|
|
94
|
-
protected getOptions(): Option<any>[];
|
|
95
|
-
protected makeRenderer(renderContext: RenderContext, untypedOptionValues: {
|
|
96
|
-
[name: string]: any;
|
|
97
|
-
}): NewtonsoftCSharpRenderer;
|
|
98
|
-
}
|
|
99
100
|
export declare class NewtonsoftCSharpRenderer extends CSharpRenderer {
|
|
100
101
|
private readonly _options;
|
|
101
102
|
private readonly _enumExtensionsNames;
|
|
@@ -135,3 +136,61 @@ export declare class NewtonsoftCSharpRenderer extends CSharpRenderer {
|
|
|
135
136
|
protected emitRequiredHelpers(): void;
|
|
136
137
|
protected needNamespace(): boolean;
|
|
137
138
|
}
|
|
139
|
+
export declare const systemTextJsonCSharpOptions: {
|
|
140
|
+
framework: EnumOption<Framework>;
|
|
141
|
+
useList: EnumOption<boolean>;
|
|
142
|
+
dense: EnumOption<boolean>;
|
|
143
|
+
namespace: StringOption;
|
|
144
|
+
version: EnumOption<Version>;
|
|
145
|
+
virtual: BooleanOption;
|
|
146
|
+
typeForAny: EnumOption<CSharpTypeForAny>;
|
|
147
|
+
useDecimal: EnumOption<boolean>;
|
|
148
|
+
} & {
|
|
149
|
+
features: EnumOption<{
|
|
150
|
+
namespaces: boolean;
|
|
151
|
+
helpers: boolean;
|
|
152
|
+
attributes: boolean;
|
|
153
|
+
}>;
|
|
154
|
+
baseclass: EnumOption<string | undefined>;
|
|
155
|
+
checkRequired: BooleanOption;
|
|
156
|
+
};
|
|
157
|
+
export declare class SystemTextJsonCSharpRenderer extends CSharpRenderer {
|
|
158
|
+
private readonly _options;
|
|
159
|
+
private readonly _enumExtensionsNames;
|
|
160
|
+
private readonly _needHelpers;
|
|
161
|
+
private readonly _needAttributes;
|
|
162
|
+
private readonly _needNamespaces;
|
|
163
|
+
constructor(targetLanguage: TargetLanguage, renderContext: RenderContext, _options: OptionValues<typeof systemTextJsonCSharpOptions>);
|
|
164
|
+
protected forbiddenNamesForGlobalNamespace(): string[];
|
|
165
|
+
protected forbiddenForObjectProperties(c: ClassType, className: Name): ForbiddenWordsInfo;
|
|
166
|
+
protected makeNameForTransformation(xf: Transformation, typeName: Name | undefined): Name;
|
|
167
|
+
protected makeNamedTypeDependencyNames(t: Type, name: Name): DependencyName[];
|
|
168
|
+
protected emitUsings(): void;
|
|
169
|
+
protected baseclassForType(_t: Type): Sourcelike | undefined;
|
|
170
|
+
protected emitDefaultFollowingComments(): void;
|
|
171
|
+
protected emitDefaultLeadingComments(): void;
|
|
172
|
+
private converterForType;
|
|
173
|
+
protected attributesForProperty(property: ClassProperty, _name: Name, _c: ClassType, jsonName: string): Sourcelike[] | undefined;
|
|
174
|
+
protected blankLinesBetweenAttributes(): boolean;
|
|
175
|
+
private topLevelResultType;
|
|
176
|
+
private emitFromJsonForTopLevel;
|
|
177
|
+
private emitDecoderSwitch;
|
|
178
|
+
private emitTokenCase;
|
|
179
|
+
private emitThrow;
|
|
180
|
+
private deserializeTypeCode;
|
|
181
|
+
private serializeValueCode;
|
|
182
|
+
private emitSerializeClass;
|
|
183
|
+
private emitCanConvert;
|
|
184
|
+
private emitReadJson;
|
|
185
|
+
private emitWriteJson;
|
|
186
|
+
private converterObject;
|
|
187
|
+
private emitConverterClass;
|
|
188
|
+
private emitDecoderTransformerCase;
|
|
189
|
+
private emitConsume;
|
|
190
|
+
private emitDecodeTransformer;
|
|
191
|
+
private stringCaseValue;
|
|
192
|
+
private emitTransformer;
|
|
193
|
+
private emitTransformation;
|
|
194
|
+
protected emitRequiredHelpers(): void;
|
|
195
|
+
protected needNamespace(): boolean;
|
|
196
|
+
}
|
package/dist/language/CSharp.js
CHANGED
|
@@ -13,6 +13,11 @@ const RendererOptions_1 = require("../RendererOptions");
|
|
|
13
13
|
const Annotation_1 = require("../Annotation");
|
|
14
14
|
const Transformers_1 = require("../Transformers");
|
|
15
15
|
const Constraints_1 = require("../attributes/Constraints");
|
|
16
|
+
var Framework;
|
|
17
|
+
(function (Framework) {
|
|
18
|
+
Framework[Framework["Newtonsoft"] = 0] = "Newtonsoft";
|
|
19
|
+
Framework[Framework["SystemTextJson"] = 1] = "SystemTextJson";
|
|
20
|
+
})(Framework = exports.Framework || (exports.Framework = {}));
|
|
16
21
|
const unicode = require("@mark.probst/unicode-properties");
|
|
17
22
|
var AccessModifier;
|
|
18
23
|
(function (AccessModifier) {
|
|
@@ -73,6 +78,7 @@ function csTypeForTransformedStringType(t) {
|
|
|
73
78
|
}
|
|
74
79
|
}
|
|
75
80
|
exports.cSharpOptions = {
|
|
81
|
+
framework: new RendererOptions_1.EnumOption("framework", "Serialization framework", [["NewtonSoft", Framework.Newtonsoft], ["SystemTextJson", Framework.SystemTextJson]], "NewtonSoft"),
|
|
76
82
|
useList: new RendererOptions_1.EnumOption("array-type", "Use T[] or List<T>", [
|
|
77
83
|
["array", false],
|
|
78
84
|
["list", true],
|
|
@@ -98,8 +104,12 @@ exports.cSharpOptions = {
|
|
|
98
104
|
], "double", "secondary"),
|
|
99
105
|
};
|
|
100
106
|
class CSharpTargetLanguage extends TargetLanguage_1.TargetLanguage {
|
|
107
|
+
constructor() {
|
|
108
|
+
super("C#", ["cs", "csharp"], "cs");
|
|
109
|
+
}
|
|
101
110
|
getOptions() {
|
|
102
111
|
return [
|
|
112
|
+
exports.cSharpOptions.framework,
|
|
103
113
|
exports.cSharpOptions.namespace,
|
|
104
114
|
exports.cSharpOptions.version,
|
|
105
115
|
exports.cSharpOptions.dense,
|
|
@@ -131,7 +141,15 @@ class CSharpTargetLanguage extends TargetLanguage_1.TargetLanguage {
|
|
|
131
141
|
return need !== "none" && need !== "nullable";
|
|
132
142
|
}
|
|
133
143
|
makeRenderer(renderContext, untypedOptionValues) {
|
|
134
|
-
|
|
144
|
+
const options = RendererOptions_1.getOptionValues(exports.cSharpOptions, untypedOptionValues);
|
|
145
|
+
switch (options.framework) {
|
|
146
|
+
case Framework.Newtonsoft:
|
|
147
|
+
return new NewtonsoftCSharpRenderer(this, renderContext, RendererOptions_1.getOptionValues(exports.newtonsoftCSharpOptions, untypedOptionValues));
|
|
148
|
+
case Framework.SystemTextJson:
|
|
149
|
+
return new SystemTextJsonCSharpRenderer(this, renderContext, RendererOptions_1.getOptionValues(exports.systemTextJsonCSharpOptions, untypedOptionValues));
|
|
150
|
+
default:
|
|
151
|
+
return Support_1.assertNever(options.framework);
|
|
152
|
+
}
|
|
135
153
|
}
|
|
136
154
|
}
|
|
137
155
|
exports.CSharpTargetLanguage = CSharpTargetLanguage;
|
|
@@ -423,6 +441,9 @@ class CSharpRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
423
441
|
emitDefaultLeadingComments() {
|
|
424
442
|
return;
|
|
425
443
|
}
|
|
444
|
+
emitDefaultFollowingComments() {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
426
447
|
needNamespace() {
|
|
427
448
|
return true;
|
|
428
449
|
}
|
|
@@ -445,6 +466,7 @@ class CSharpRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
445
466
|
this.emitUsings();
|
|
446
467
|
this.emitTypesAndSupport();
|
|
447
468
|
}
|
|
469
|
+
this.emitDefaultFollowingComments();
|
|
448
470
|
}
|
|
449
471
|
}
|
|
450
472
|
exports.CSharpRenderer = CSharpRenderer;
|
|
@@ -461,29 +483,6 @@ exports.newtonsoftCSharpOptions = Object.assign({}, exports.cSharpOptions, {
|
|
|
461
483
|
], "Object", "secondary"),
|
|
462
484
|
checkRequired: new RendererOptions_1.BooleanOption("check-required", "Fail if required properties are missing", false),
|
|
463
485
|
});
|
|
464
|
-
class NewtonsoftCSharpTargetLanguage extends CSharpTargetLanguage {
|
|
465
|
-
constructor() {
|
|
466
|
-
super("C#", ["cs", "csharp"], "cs");
|
|
467
|
-
}
|
|
468
|
-
getOptions() {
|
|
469
|
-
return [
|
|
470
|
-
exports.newtonsoftCSharpOptions.namespace,
|
|
471
|
-
exports.newtonsoftCSharpOptions.version,
|
|
472
|
-
exports.newtonsoftCSharpOptions.dense,
|
|
473
|
-
exports.newtonsoftCSharpOptions.useList,
|
|
474
|
-
exports.newtonsoftCSharpOptions.useDecimal,
|
|
475
|
-
exports.newtonsoftCSharpOptions.features,
|
|
476
|
-
exports.newtonsoftCSharpOptions.checkRequired,
|
|
477
|
-
exports.newtonsoftCSharpOptions.typeForAny,
|
|
478
|
-
exports.newtonsoftCSharpOptions.baseclass,
|
|
479
|
-
exports.newtonsoftCSharpOptions.virtual,
|
|
480
|
-
];
|
|
481
|
-
}
|
|
482
|
-
makeRenderer(renderContext, untypedOptionValues) {
|
|
483
|
-
return new NewtonsoftCSharpRenderer(this, renderContext, RendererOptions_1.getOptionValues(exports.newtonsoftCSharpOptions, untypedOptionValues));
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
exports.NewtonsoftCSharpTargetLanguage = NewtonsoftCSharpTargetLanguage;
|
|
487
486
|
class NewtonsoftCSharpRenderer extends CSharpRenderer {
|
|
488
487
|
constructor(targetLanguage, renderContext, _options) {
|
|
489
488
|
super(targetLanguage, renderContext, _options);
|
|
@@ -1080,3 +1079,765 @@ class NewtonsoftCSharpRenderer extends CSharpRenderer {
|
|
|
1080
1079
|
}
|
|
1081
1080
|
}
|
|
1082
1081
|
exports.NewtonsoftCSharpRenderer = NewtonsoftCSharpRenderer;
|
|
1082
|
+
exports.systemTextJsonCSharpOptions = Object.assign({}, exports.cSharpOptions, {
|
|
1083
|
+
features: new RendererOptions_1.EnumOption("features", "Output features", [
|
|
1084
|
+
["complete", { namespaces: true, helpers: true, attributes: true }],
|
|
1085
|
+
["attributes-only", { namespaces: true, helpers: false, attributes: true }],
|
|
1086
|
+
["just-types-and-namespace", { namespaces: true, helpers: false, attributes: false }],
|
|
1087
|
+
["just-types", { namespaces: true, helpers: false, attributes: false }],
|
|
1088
|
+
]),
|
|
1089
|
+
baseclass: new RendererOptions_1.EnumOption("base-class", "Base class", [
|
|
1090
|
+
["EntityData", "EntityData"],
|
|
1091
|
+
["Object", undefined],
|
|
1092
|
+
], "Object", "secondary"),
|
|
1093
|
+
checkRequired: new RendererOptions_1.BooleanOption("check-required", "Fail if required properties are missing", false),
|
|
1094
|
+
});
|
|
1095
|
+
class SystemTextJsonCSharpRenderer extends CSharpRenderer {
|
|
1096
|
+
constructor(targetLanguage, renderContext, _options) {
|
|
1097
|
+
super(targetLanguage, renderContext, _options);
|
|
1098
|
+
this._options = _options;
|
|
1099
|
+
this._enumExtensionsNames = new Map();
|
|
1100
|
+
this._needHelpers = _options.features.helpers;
|
|
1101
|
+
this._needAttributes = _options.features.attributes;
|
|
1102
|
+
this._needNamespaces = _options.features.namespaces;
|
|
1103
|
+
}
|
|
1104
|
+
forbiddenNamesForGlobalNamespace() {
|
|
1105
|
+
const forbidden = [
|
|
1106
|
+
"Converter",
|
|
1107
|
+
"JsonConverter",
|
|
1108
|
+
"JsonSerializer",
|
|
1109
|
+
"JsonWriter",
|
|
1110
|
+
"JsonToken",
|
|
1111
|
+
"Serialize",
|
|
1112
|
+
"JsonSerializerOptions",
|
|
1113
|
+
// "Newtonsoft",
|
|
1114
|
+
// "MetadataPropertyHandling",
|
|
1115
|
+
// "DateParseHandling",
|
|
1116
|
+
"FromJson",
|
|
1117
|
+
"Required"
|
|
1118
|
+
];
|
|
1119
|
+
if (this._options.dense) {
|
|
1120
|
+
forbidden.push("J", "R", "N");
|
|
1121
|
+
}
|
|
1122
|
+
if (this._options.baseclass !== undefined) {
|
|
1123
|
+
forbidden.push(this._options.baseclass);
|
|
1124
|
+
}
|
|
1125
|
+
return super.forbiddenNamesForGlobalNamespace().concat(forbidden);
|
|
1126
|
+
}
|
|
1127
|
+
forbiddenForObjectProperties(c, className) {
|
|
1128
|
+
const result = super.forbiddenForObjectProperties(c, className);
|
|
1129
|
+
result.names = result.names.concat(["ToJson", "FromJson", "Required"]);
|
|
1130
|
+
return result;
|
|
1131
|
+
}
|
|
1132
|
+
makeNameForTransformation(xf, typeName) {
|
|
1133
|
+
if (typeName === undefined) {
|
|
1134
|
+
let xfer = xf.transformer;
|
|
1135
|
+
if (xfer instanceof Transformers_1.DecodingTransformer && xfer.consumer !== undefined) {
|
|
1136
|
+
xfer = xfer.consumer;
|
|
1137
|
+
}
|
|
1138
|
+
return new Naming_1.SimpleName([`${xfer.kind}_converter`], namingFunction, ConvenienceRenderer_1.inferredNameOrder + 30);
|
|
1139
|
+
}
|
|
1140
|
+
return new Naming_1.DependencyName(namingFunction, typeName.order + 30, lookup => `${lookup(typeName)}_converter`);
|
|
1141
|
+
}
|
|
1142
|
+
makeNamedTypeDependencyNames(t, name) {
|
|
1143
|
+
if (!(t instanceof Type_1.EnumType))
|
|
1144
|
+
return [];
|
|
1145
|
+
const extensionsName = new Naming_1.DependencyName(namingFunction, name.order + 30, lookup => `${lookup(name)}_extensions`);
|
|
1146
|
+
this._enumExtensionsNames.set(name, extensionsName);
|
|
1147
|
+
return [extensionsName];
|
|
1148
|
+
}
|
|
1149
|
+
emitUsings() {
|
|
1150
|
+
// FIXME: We need System.Collections.Generic whenever we have maps or use List.
|
|
1151
|
+
if (!this._needAttributes && !this._needHelpers)
|
|
1152
|
+
return;
|
|
1153
|
+
super.emitUsings();
|
|
1154
|
+
this.ensureBlankLine();
|
|
1155
|
+
for (const ns of ["System.Text.Json", "System.Text.Json.Serialization", "System.Globalization"]) {
|
|
1156
|
+
this.emitUsing(ns);
|
|
1157
|
+
}
|
|
1158
|
+
if (this._options.dense) {
|
|
1159
|
+
this.emitUsing([denseJsonPropertyName, " = System.Text.Json.Serialization.JsonPropertyNameAttribute"]);
|
|
1160
|
+
// this.emitUsing([denseRequiredEnumName, " = Newtonsoft.Json.Required"]);
|
|
1161
|
+
this.emitUsing([denseNullValueHandlingEnumName, " = System.Text.Json.Serialization.JsonIgnoreCondition"]);
|
|
1162
|
+
}
|
|
1163
|
+
if (this._options.baseclass === "EntityData") {
|
|
1164
|
+
this.emitUsing("Microsoft.Azure.Mobile.Server");
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
baseclassForType(_t) {
|
|
1168
|
+
return this._options.baseclass;
|
|
1169
|
+
}
|
|
1170
|
+
emitDefaultFollowingComments() {
|
|
1171
|
+
if (!this._needHelpers)
|
|
1172
|
+
return;
|
|
1173
|
+
this.emitLine("#pragma warning restore CS8618");
|
|
1174
|
+
this.emitLine("#pragma warning restore CS8601");
|
|
1175
|
+
this.emitLine("#pragma warning restore CS8603");
|
|
1176
|
+
}
|
|
1177
|
+
emitDefaultLeadingComments() {
|
|
1178
|
+
if (!this._needHelpers)
|
|
1179
|
+
return;
|
|
1180
|
+
this.emitLine("// <auto-generated />");
|
|
1181
|
+
this.emitLine("//");
|
|
1182
|
+
this.emitLine("// To parse this JSON data, add NuGet 'System.Text.Json' then do", this.topLevels.size === 1 ? "" : " one of these", ":");
|
|
1183
|
+
this.emitLine("//");
|
|
1184
|
+
this.emitLine("// using ", this._options.namespace, ";");
|
|
1185
|
+
this.emitLine("//");
|
|
1186
|
+
this.forEachTopLevel("none", (t, topLevelName) => {
|
|
1187
|
+
let rhs;
|
|
1188
|
+
if (t instanceof Type_1.EnumType) {
|
|
1189
|
+
rhs = ["JsonSerializer.Deserialize<", topLevelName, ">(jsonString)"];
|
|
1190
|
+
}
|
|
1191
|
+
else {
|
|
1192
|
+
rhs = [topLevelName, ".FromJson(jsonString)"];
|
|
1193
|
+
}
|
|
1194
|
+
this.emitLine("// var ", Source_1.modifySource(Strings_1.camelCase, topLevelName), " = ", rhs, ";");
|
|
1195
|
+
});
|
|
1196
|
+
// fix: should this be an option? Or respond to an existing option?
|
|
1197
|
+
this.emitLine("#nullable enable");
|
|
1198
|
+
this.emitLine("#pragma warning disable CS8618");
|
|
1199
|
+
this.emitLine("#pragma warning disable CS8601");
|
|
1200
|
+
this.emitLine("#pragma warning disable CS8603");
|
|
1201
|
+
}
|
|
1202
|
+
converterForType(t) {
|
|
1203
|
+
let xf = Transformers_1.transformationForType(t);
|
|
1204
|
+
if (xf === undefined && t instanceof Type_1.UnionType) {
|
|
1205
|
+
const maybeNullable = TypeUtils_1.nullableFromUnion(t);
|
|
1206
|
+
if (maybeNullable !== null) {
|
|
1207
|
+
t = maybeNullable;
|
|
1208
|
+
xf = Transformers_1.transformationForType(t);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
if (xf === undefined)
|
|
1212
|
+
return undefined;
|
|
1213
|
+
if (alwaysApplyTransformation(xf))
|
|
1214
|
+
return undefined;
|
|
1215
|
+
return Support_1.defined(this.nameForTransformation(t));
|
|
1216
|
+
}
|
|
1217
|
+
attributesForProperty(property, _name, _c, jsonName) {
|
|
1218
|
+
if (!this._needAttributes)
|
|
1219
|
+
return undefined;
|
|
1220
|
+
const attributes = [];
|
|
1221
|
+
const jsonPropertyName = this._options.dense ? denseJsonPropertyName : "JsonPropertyName";
|
|
1222
|
+
const escapedName = Strings_1.utf16StringEscape(jsonName);
|
|
1223
|
+
const isNullable = Transformers_1.followTargetType(property.type).isNullable;
|
|
1224
|
+
const isOptional = property.isOptional;
|
|
1225
|
+
if (isOptional && !isNullable) {
|
|
1226
|
+
attributes.push(["[", "JsonIgnore", "(Condition = JsonIgnoreCondition.WhenWritingNull)]"]);
|
|
1227
|
+
}
|
|
1228
|
+
// const requiredClass = this._options.dense ? "R" : "Required";
|
|
1229
|
+
// const nullValueHandlingClass = this._options.dense ? "N" : "NullValueHandling";
|
|
1230
|
+
// const nullValueHandling = isOptional && !isNullable ? [", NullValueHandling = ", nullValueHandlingClass, ".Ignore"] : [];
|
|
1231
|
+
// let required: Sourcelike;
|
|
1232
|
+
// if (!this._options.checkRequired || (isOptional && isNullable)) {
|
|
1233
|
+
// required = [nullValueHandling];
|
|
1234
|
+
// } else if (isOptional && !isNullable) {
|
|
1235
|
+
// required = [", Required = ", requiredClass, ".DisallowNull", nullValueHandling];
|
|
1236
|
+
// } else if (!isOptional && isNullable) {
|
|
1237
|
+
// required = [", Required = ", requiredClass, ".AllowNull"];
|
|
1238
|
+
// } else {
|
|
1239
|
+
// required = [", Required = ", requiredClass, ".Always", nullValueHandling];
|
|
1240
|
+
// }
|
|
1241
|
+
attributes.push(["[", jsonPropertyName, '("', escapedName, '")]']);
|
|
1242
|
+
const converter = this.converterForType(property.type);
|
|
1243
|
+
if (converter !== undefined) {
|
|
1244
|
+
attributes.push(["[JsonConverter(typeof(", converter, "))]"]);
|
|
1245
|
+
}
|
|
1246
|
+
return attributes;
|
|
1247
|
+
}
|
|
1248
|
+
blankLinesBetweenAttributes() {
|
|
1249
|
+
return this._needAttributes && !this._options.dense;
|
|
1250
|
+
}
|
|
1251
|
+
// The "this" type can't be `dynamic`, so we have to force it to `object`.
|
|
1252
|
+
topLevelResultType(t) {
|
|
1253
|
+
return t.kind === "any" || t.kind === "none" ? "object" : this.csType(t);
|
|
1254
|
+
}
|
|
1255
|
+
emitFromJsonForTopLevel(t, name) {
|
|
1256
|
+
if (t instanceof Type_1.EnumType)
|
|
1257
|
+
return;
|
|
1258
|
+
let partial;
|
|
1259
|
+
let typeKind;
|
|
1260
|
+
const definedType = this.namedTypeToNameForTopLevel(t);
|
|
1261
|
+
if (definedType !== undefined) {
|
|
1262
|
+
partial = "partial ";
|
|
1263
|
+
typeKind = definedType instanceof Type_1.ClassType ? "class" : "struct";
|
|
1264
|
+
}
|
|
1265
|
+
else {
|
|
1266
|
+
partial = "";
|
|
1267
|
+
typeKind = "class";
|
|
1268
|
+
}
|
|
1269
|
+
const csType = this.topLevelResultType(t);
|
|
1270
|
+
this.emitType(undefined, AccessModifier.Public, [partial, typeKind], name, this.baseclassForType(t), () => {
|
|
1271
|
+
// FIXME: Make FromJson a Named
|
|
1272
|
+
this.emitExpressionMember(["public static ", csType, " FromJson(string json)"], ["JsonSerializer.Deserialize<", csType, ">(json, ", this._options.namespace, ".Converter.Settings)"]);
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1275
|
+
emitDecoderSwitch(emitBody) {
|
|
1276
|
+
this.emitLine("switch (reader.TokenType)");
|
|
1277
|
+
this.emitBlock(emitBody);
|
|
1278
|
+
}
|
|
1279
|
+
emitTokenCase(tokenType) {
|
|
1280
|
+
this.emitLine("case JsonTokenType.", tokenType, ":");
|
|
1281
|
+
}
|
|
1282
|
+
emitThrow(message) {
|
|
1283
|
+
this.emitLine("throw new Exception(", message, ");");
|
|
1284
|
+
}
|
|
1285
|
+
deserializeTypeCode(typeName) {
|
|
1286
|
+
switch (typeName) {
|
|
1287
|
+
case "bool":
|
|
1288
|
+
return ["reader.GetBoolean()"];
|
|
1289
|
+
case "long":
|
|
1290
|
+
return ["reader.GetInt64()"];
|
|
1291
|
+
case "decimal":
|
|
1292
|
+
return ["reader.GetDecimal()"];
|
|
1293
|
+
case "double":
|
|
1294
|
+
return ["reader.GetDouble()"];
|
|
1295
|
+
case "string":
|
|
1296
|
+
return ["reader.GetString()"];
|
|
1297
|
+
default:
|
|
1298
|
+
return ["JsonSerializer.Deserialize<", typeName, ">(ref reader, options)"];
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
serializeValueCode(value) {
|
|
1302
|
+
if (value !== "null")
|
|
1303
|
+
return ["JsonSerializer.Serialize(writer, ", value, ", options)"];
|
|
1304
|
+
else
|
|
1305
|
+
return ["writer.WriteNullValue()"];
|
|
1306
|
+
}
|
|
1307
|
+
emitSerializeClass() {
|
|
1308
|
+
// FIXME: Make Serialize a Named
|
|
1309
|
+
this.emitType(undefined, AccessModifier.Public, "static class", "Serialize", undefined, () => {
|
|
1310
|
+
// Sometimes multiple top-levels will resolve to the same type, so we have to take care
|
|
1311
|
+
// not to emit more than one extension method for the same type.
|
|
1312
|
+
const seenTypes = new Set();
|
|
1313
|
+
this.forEachTopLevel("none", t => {
|
|
1314
|
+
// FIXME: Make ToJson a Named
|
|
1315
|
+
if (!seenTypes.has(t)) {
|
|
1316
|
+
seenTypes.add(t);
|
|
1317
|
+
this.emitExpressionMember(["public static string ToJson(this ", this.topLevelResultType(t), " self)"], ["JsonSerializer.Serialize(self, ", this._options.namespace, ".Converter.Settings)"]);
|
|
1318
|
+
}
|
|
1319
|
+
});
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
emitCanConvert(expr) {
|
|
1323
|
+
this.emitExpressionMember("public override bool CanConvert(Type t)", expr);
|
|
1324
|
+
}
|
|
1325
|
+
emitReadJson(emitBody, csType) {
|
|
1326
|
+
this.emitLine("public override ", csType, " Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)");
|
|
1327
|
+
this.emitBlock(emitBody);
|
|
1328
|
+
}
|
|
1329
|
+
emitWriteJson(variable, emitBody, csType) {
|
|
1330
|
+
this.emitLine("public override void Write(Utf8JsonWriter writer, ", csType, " ", variable, ", JsonSerializerOptions options)");
|
|
1331
|
+
this.emitBlock(emitBody);
|
|
1332
|
+
}
|
|
1333
|
+
converterObject(converterName) {
|
|
1334
|
+
// FIXME: Get a singleton
|
|
1335
|
+
return [converterName, ".Singleton"];
|
|
1336
|
+
}
|
|
1337
|
+
emitConverterClass() {
|
|
1338
|
+
// FIXME: Make Converter a Named
|
|
1339
|
+
const converterName = ["Converter"];
|
|
1340
|
+
this.emitType(undefined, AccessModifier.Internal, "static class", converterName, undefined, () => {
|
|
1341
|
+
// Do not use .Web as defaults. That turns on caseInsensitive property names and will fail the keywords test.
|
|
1342
|
+
this.emitLine("public static readonly JsonSerializerOptions Settings = new(JsonSerializerDefaults.General)");
|
|
1343
|
+
this.emitBlock(() => {
|
|
1344
|
+
// this.emitLine("MetadataPropertyHandling = MetadataPropertyHandling.Ignore,");
|
|
1345
|
+
// this.emitLine("DateParseHandling = DateParseHandling.None,");
|
|
1346
|
+
this.emitLine("Converters =");
|
|
1347
|
+
this.emitLine("{");
|
|
1348
|
+
this.indent(() => {
|
|
1349
|
+
for (const [t, converter] of this.typesWithNamedTransformations) {
|
|
1350
|
+
if (alwaysApplyTransformation(Support_1.defined(Transformers_1.transformationForType(t)))) {
|
|
1351
|
+
this.emitLine(this.converterObject(converter), ",");
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
this.emitLine("new DateOnlyConverter(),");
|
|
1355
|
+
this.emitLine("new TimeOnlyConverter(),");
|
|
1356
|
+
this.emitLine("IsoDateTimeOffsetConverter.Singleton");
|
|
1357
|
+
// this.emitLine("new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }");
|
|
1358
|
+
});
|
|
1359
|
+
this.emitLine(`},`);
|
|
1360
|
+
}, true);
|
|
1361
|
+
});
|
|
1362
|
+
}
|
|
1363
|
+
emitDecoderTransformerCase(tokenCases, variableName, xfer, targetType, emitFinish) {
|
|
1364
|
+
if (xfer === undefined)
|
|
1365
|
+
return;
|
|
1366
|
+
for (const tokenCase of tokenCases) {
|
|
1367
|
+
this.emitTokenCase(tokenCase);
|
|
1368
|
+
}
|
|
1369
|
+
this.indent(() => {
|
|
1370
|
+
const allHandled = this.emitDecodeTransformer(xfer, targetType, emitFinish, variableName);
|
|
1371
|
+
if (!allHandled) {
|
|
1372
|
+
this.emitLine("break;");
|
|
1373
|
+
}
|
|
1374
|
+
});
|
|
1375
|
+
}
|
|
1376
|
+
emitConsume(value, consumer, targetType, emitFinish) {
|
|
1377
|
+
if (consumer === undefined) {
|
|
1378
|
+
emitFinish(value);
|
|
1379
|
+
return true;
|
|
1380
|
+
}
|
|
1381
|
+
else {
|
|
1382
|
+
return this.emitTransformer(value, consumer, targetType, emitFinish);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
emitDecodeTransformer(xfer, targetType, emitFinish, variableName = "value") {
|
|
1386
|
+
if (xfer instanceof Transformers_1.DecodingTransformer) {
|
|
1387
|
+
const source = xfer.sourceType;
|
|
1388
|
+
const converter = this.converterForType(targetType);
|
|
1389
|
+
if (converter !== undefined) {
|
|
1390
|
+
const typeSource = this.csType(targetType);
|
|
1391
|
+
this.emitLine("var converter = ", this.converterObject(converter), ";");
|
|
1392
|
+
this.emitLine("var ", variableName, " = (", typeSource, ")converter.ReadJson(reader, typeof(", typeSource, "), null, serializer);");
|
|
1393
|
+
}
|
|
1394
|
+
else if (source.kind !== "null") {
|
|
1395
|
+
let output = targetType.kind === "double" ? targetType : source;
|
|
1396
|
+
this.emitLine("var ", variableName, " = ", this.deserializeTypeCode(this.csType(output)), ";");
|
|
1397
|
+
}
|
|
1398
|
+
return this.emitConsume(variableName, xfer.consumer, targetType, emitFinish);
|
|
1399
|
+
}
|
|
1400
|
+
else if (xfer instanceof Transformers_1.ArrayDecodingTransformer) {
|
|
1401
|
+
// FIXME: Consume StartArray
|
|
1402
|
+
if (!(targetType instanceof Type_1.ArrayType)) {
|
|
1403
|
+
return Support_1.panic("Array decoding must produce an array type");
|
|
1404
|
+
}
|
|
1405
|
+
// FIXME: handle EOF
|
|
1406
|
+
this.emitLine("reader.Read();");
|
|
1407
|
+
this.emitLine("var ", variableName, " = new List<", this.csType(targetType.items), ">();");
|
|
1408
|
+
this.emitLine("while (reader.TokenType != JsonToken.EndArray)");
|
|
1409
|
+
this.emitBlock(() => {
|
|
1410
|
+
this.emitDecodeTransformer(xfer.itemTransformer, xfer.itemTargetType, v => this.emitLine(variableName, ".Add(", v, ");"), "arrayItem");
|
|
1411
|
+
// FIXME: handle EOF
|
|
1412
|
+
this.emitLine("reader.Read();");
|
|
1413
|
+
});
|
|
1414
|
+
let result = variableName;
|
|
1415
|
+
if (!this._options.useList) {
|
|
1416
|
+
result = [result, ".ToArray()"];
|
|
1417
|
+
}
|
|
1418
|
+
emitFinish(result);
|
|
1419
|
+
return true;
|
|
1420
|
+
}
|
|
1421
|
+
else if (xfer instanceof Transformers_1.DecodingChoiceTransformer) {
|
|
1422
|
+
this.emitDecoderSwitch(() => {
|
|
1423
|
+
const nullTransformer = xfer.nullTransformer;
|
|
1424
|
+
if (nullTransformer !== undefined) {
|
|
1425
|
+
this.emitTokenCase("Null");
|
|
1426
|
+
this.indent(() => {
|
|
1427
|
+
const allHandled = this.emitDecodeTransformer(nullTransformer, targetType, emitFinish, "null");
|
|
1428
|
+
if (!allHandled) {
|
|
1429
|
+
this.emitLine("break");
|
|
1430
|
+
}
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1433
|
+
this.emitDecoderTransformerCase(["Number"], "integerValue", xfer.integerTransformer, targetType, emitFinish);
|
|
1434
|
+
this.emitDecoderTransformerCase(["Number"],
|
|
1435
|
+
// xfer.integerTransformer === undefined ? ["Integer", "Float"] : ["Float"],
|
|
1436
|
+
"doubleValue", xfer.doubleTransformer, targetType, emitFinish);
|
|
1437
|
+
this.emitDecoderTransformerCase(["True", "False"], "boolValue", xfer.boolTransformer, targetType, emitFinish);
|
|
1438
|
+
this.emitDecoderTransformerCase(
|
|
1439
|
+
// ["String", "Date"],
|
|
1440
|
+
["String"], "stringValue", xfer.stringTransformer, targetType, emitFinish);
|
|
1441
|
+
this.emitDecoderTransformerCase(["StartObject"], "objectValue", xfer.objectTransformer, targetType, emitFinish);
|
|
1442
|
+
this.emitDecoderTransformerCase(["StartArray"], "arrayValue", xfer.arrayTransformer, targetType, emitFinish);
|
|
1443
|
+
});
|
|
1444
|
+
return false;
|
|
1445
|
+
}
|
|
1446
|
+
else {
|
|
1447
|
+
return Support_1.panic("Unknown transformer");
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
stringCaseValue(t, stringCase) {
|
|
1451
|
+
if (t.kind === "string") {
|
|
1452
|
+
return ['"', Strings_1.utf16StringEscape(stringCase), '"'];
|
|
1453
|
+
}
|
|
1454
|
+
else if (t instanceof Type_1.EnumType) {
|
|
1455
|
+
return [this.nameForNamedType(t), ".", this.nameForEnumCase(t, stringCase)];
|
|
1456
|
+
}
|
|
1457
|
+
return Support_1.panic(`Type ${t.kind} does not have string cases`);
|
|
1458
|
+
}
|
|
1459
|
+
emitTransformer(variable, xfer, targetType, emitFinish) {
|
|
1460
|
+
function directTargetType(continuation) {
|
|
1461
|
+
if (continuation === undefined) {
|
|
1462
|
+
return targetType;
|
|
1463
|
+
}
|
|
1464
|
+
return Transformers_1.followTargetType(continuation.sourceType);
|
|
1465
|
+
}
|
|
1466
|
+
if (xfer instanceof Transformers_1.ChoiceTransformer) {
|
|
1467
|
+
const caseXfers = xfer.transformers;
|
|
1468
|
+
if (caseXfers.length > 1 && caseXfers.every(caseXfer => caseXfer instanceof Transformers_1.StringMatchTransformer)) {
|
|
1469
|
+
this.emitLine("switch (", variable, ")");
|
|
1470
|
+
this.emitBlock(() => {
|
|
1471
|
+
for (const caseXfer of caseXfers) {
|
|
1472
|
+
const matchXfer = caseXfer;
|
|
1473
|
+
const value = this.stringCaseValue(Transformers_1.followTargetType(matchXfer.sourceType), matchXfer.stringCase);
|
|
1474
|
+
this.emitLine("case ", value, ":");
|
|
1475
|
+
this.indent(() => {
|
|
1476
|
+
const allDone = this.emitTransformer(variable, matchXfer.transformer, targetType, emitFinish);
|
|
1477
|
+
if (!allDone) {
|
|
1478
|
+
this.emitLine("break;");
|
|
1479
|
+
}
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
});
|
|
1483
|
+
// FIXME: Can we check for exhaustiveness? For enums it should be easy.
|
|
1484
|
+
return false;
|
|
1485
|
+
}
|
|
1486
|
+
else {
|
|
1487
|
+
for (const caseXfer of caseXfers) {
|
|
1488
|
+
this.emitTransformer(variable, caseXfer, targetType, emitFinish);
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
else if (xfer instanceof Transformers_1.UnionMemberMatchTransformer) {
|
|
1493
|
+
const memberType = xfer.memberType;
|
|
1494
|
+
const maybeNullable = TypeUtils_1.nullableFromUnion(xfer.sourceType);
|
|
1495
|
+
let test;
|
|
1496
|
+
let member;
|
|
1497
|
+
if (maybeNullable !== null) {
|
|
1498
|
+
if (memberType.kind === "null") {
|
|
1499
|
+
test = [variable, " == null"];
|
|
1500
|
+
member = "null";
|
|
1501
|
+
}
|
|
1502
|
+
else {
|
|
1503
|
+
test = [variable, " != null"];
|
|
1504
|
+
member = variable;
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
else if (memberType.kind === "null") {
|
|
1508
|
+
test = [variable, ".IsNull"];
|
|
1509
|
+
member = "null";
|
|
1510
|
+
}
|
|
1511
|
+
else {
|
|
1512
|
+
const memberName = this.nameForUnionMember(xfer.sourceType, memberType);
|
|
1513
|
+
member = [variable, ".", memberName];
|
|
1514
|
+
test = [member, " != null"];
|
|
1515
|
+
}
|
|
1516
|
+
if (memberType.kind !== "null" && isValueType(memberType)) {
|
|
1517
|
+
member = [member, ".Value"];
|
|
1518
|
+
}
|
|
1519
|
+
this.emitLine("if (", test, ")");
|
|
1520
|
+
this.emitBlock(() => this.emitTransformer(member, xfer.transformer, targetType, emitFinish));
|
|
1521
|
+
}
|
|
1522
|
+
else if (xfer instanceof Transformers_1.StringMatchTransformer) {
|
|
1523
|
+
const value = this.stringCaseValue(Transformers_1.followTargetType(xfer.sourceType), xfer.stringCase);
|
|
1524
|
+
this.emitLine("if (", variable, " == ", value, ")");
|
|
1525
|
+
this.emitBlock(() => this.emitTransformer(variable, xfer.transformer, targetType, emitFinish));
|
|
1526
|
+
}
|
|
1527
|
+
else if (xfer instanceof Transformers_1.EncodingTransformer) {
|
|
1528
|
+
const converter = this.converterForType(xfer.sourceType);
|
|
1529
|
+
if (converter !== undefined) {
|
|
1530
|
+
this.emitLine("var converter = ", this.converterObject(converter), ";");
|
|
1531
|
+
this.emitLine("converter.WriteJson(writer, ", variable, ", serializer);");
|
|
1532
|
+
}
|
|
1533
|
+
else {
|
|
1534
|
+
this.emitLine(this.serializeValueCode(variable), ";");
|
|
1535
|
+
}
|
|
1536
|
+
emitFinish([]);
|
|
1537
|
+
return true;
|
|
1538
|
+
}
|
|
1539
|
+
else if (xfer instanceof Transformers_1.ArrayEncodingTransformer) {
|
|
1540
|
+
this.emitLine("writer.WriteStartArray();");
|
|
1541
|
+
const itemVariable = "arrayItem";
|
|
1542
|
+
this.emitLine("foreach (var ", itemVariable, " in ", variable, ")");
|
|
1543
|
+
this.emitBlock(() => {
|
|
1544
|
+
this.emitTransformer(itemVariable, xfer.itemTransformer, xfer.itemTargetType, () => {
|
|
1545
|
+
return;
|
|
1546
|
+
});
|
|
1547
|
+
});
|
|
1548
|
+
this.emitLine("writer.WriteEndArray();");
|
|
1549
|
+
emitFinish([]);
|
|
1550
|
+
return true;
|
|
1551
|
+
}
|
|
1552
|
+
else if (xfer instanceof Transformers_1.ParseStringTransformer) {
|
|
1553
|
+
const immediateTargetType = xfer.consumer === undefined ? targetType : xfer.consumer.sourceType;
|
|
1554
|
+
switch (immediateTargetType.kind) {
|
|
1555
|
+
case "date-time":
|
|
1556
|
+
this.emitLine("DateTimeOffset dt;");
|
|
1557
|
+
this.emitLine("if (DateTimeOffset.TryParse(", variable, ", out dt))");
|
|
1558
|
+
this.emitBlock(() => this.emitConsume("dt", xfer.consumer, targetType, emitFinish));
|
|
1559
|
+
break;
|
|
1560
|
+
case "uuid":
|
|
1561
|
+
this.emitLine("Guid guid;");
|
|
1562
|
+
this.emitLine("if (Guid.TryParse(", variable, ", out guid))");
|
|
1563
|
+
this.emitBlock(() => this.emitConsume("guid", xfer.consumer, targetType, emitFinish));
|
|
1564
|
+
break;
|
|
1565
|
+
case "uri":
|
|
1566
|
+
this.emitLine("try");
|
|
1567
|
+
this.emitBlock(() => {
|
|
1568
|
+
// this.emitLine("var uri = new Uri(", variable, ");");
|
|
1569
|
+
// The default value about:blank should never happen, but this way we avoid a null reference warning.
|
|
1570
|
+
this.emitLine("var uri = new Uri(\"about:blank\");");
|
|
1571
|
+
this.emitLine("if (!string.IsNullOrEmpty(stringValue))");
|
|
1572
|
+
this.emitBlock(() => {
|
|
1573
|
+
this.emitLine("uri = new Uri(", variable, ");");
|
|
1574
|
+
});
|
|
1575
|
+
this.emitConsume("uri", xfer.consumer, targetType, emitFinish);
|
|
1576
|
+
});
|
|
1577
|
+
this.emitLine("catch (UriFormatException) {}");
|
|
1578
|
+
break;
|
|
1579
|
+
case "integer":
|
|
1580
|
+
this.emitLine("long l;");
|
|
1581
|
+
this.emitLine("if (Int64.TryParse(", variable, ", out l))");
|
|
1582
|
+
this.emitBlock(() => this.emitConsume("l", xfer.consumer, targetType, emitFinish));
|
|
1583
|
+
break;
|
|
1584
|
+
case "bool":
|
|
1585
|
+
this.emitLine("bool b;");
|
|
1586
|
+
this.emitLine("if (Boolean.TryParse(", variable, ", out b))");
|
|
1587
|
+
this.emitBlock(() => this.emitConsume("b", xfer.consumer, targetType, emitFinish));
|
|
1588
|
+
break;
|
|
1589
|
+
default:
|
|
1590
|
+
return Support_1.panic(`Parsing string to ${immediateTargetType.kind} not supported`);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
else if (xfer instanceof Transformers_1.StringifyTransformer) {
|
|
1594
|
+
switch (xfer.sourceType.kind) {
|
|
1595
|
+
case "date-time":
|
|
1596
|
+
return this.emitConsume([variable, '.ToString("o", System.Globalization.CultureInfo.InvariantCulture)'], xfer.consumer, targetType, emitFinish);
|
|
1597
|
+
case "uuid":
|
|
1598
|
+
return this.emitConsume([variable, '.ToString("D", System.Globalization.CultureInfo.InvariantCulture)'], xfer.consumer, targetType, emitFinish);
|
|
1599
|
+
case "integer":
|
|
1600
|
+
case "uri":
|
|
1601
|
+
return this.emitConsume([variable, ".ToString()"], xfer.consumer, targetType, emitFinish);
|
|
1602
|
+
case "bool":
|
|
1603
|
+
this.emitLine("var boolString = ", variable, ' ? "true" : "false";');
|
|
1604
|
+
return this.emitConsume("boolString", xfer.consumer, targetType, emitFinish);
|
|
1605
|
+
default:
|
|
1606
|
+
return Support_1.panic(`Stringifying ${xfer.sourceType.kind} not supported`);
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
else if (xfer instanceof Transformers_1.StringProducerTransformer) {
|
|
1610
|
+
const value = this.stringCaseValue(directTargetType(xfer.consumer), xfer.result);
|
|
1611
|
+
return this.emitConsume(value, xfer.consumer, targetType, emitFinish);
|
|
1612
|
+
}
|
|
1613
|
+
else if (xfer instanceof Transformers_1.MinMaxLengthCheckTransformer) {
|
|
1614
|
+
const min = xfer.minLength;
|
|
1615
|
+
const max = xfer.maxLength;
|
|
1616
|
+
const conditions = [];
|
|
1617
|
+
if (min !== undefined) {
|
|
1618
|
+
conditions.push([variable, ".Length >= ", min.toString()]);
|
|
1619
|
+
}
|
|
1620
|
+
if (max !== undefined) {
|
|
1621
|
+
conditions.push([variable, ".Length <= ", max.toString()]);
|
|
1622
|
+
}
|
|
1623
|
+
this.emitLine("if (", collection_utils_1.arrayIntercalate([" && "], conditions), ")");
|
|
1624
|
+
this.emitBlock(() => this.emitConsume(variable, xfer.consumer, targetType, emitFinish));
|
|
1625
|
+
return false;
|
|
1626
|
+
}
|
|
1627
|
+
else if (xfer instanceof Transformers_1.MinMaxValueTransformer) {
|
|
1628
|
+
const min = xfer.minimum;
|
|
1629
|
+
const max = xfer.maximum;
|
|
1630
|
+
const conditions = [];
|
|
1631
|
+
if (min !== undefined) {
|
|
1632
|
+
conditions.push([variable, " >= ", min.toString()]);
|
|
1633
|
+
}
|
|
1634
|
+
if (max !== undefined) {
|
|
1635
|
+
conditions.push([variable, " <= ", max.toString()]);
|
|
1636
|
+
}
|
|
1637
|
+
this.emitLine("if (", collection_utils_1.arrayIntercalate([" && "], conditions), ")");
|
|
1638
|
+
this.emitBlock(() => this.emitConsume(variable, xfer.consumer, targetType, emitFinish));
|
|
1639
|
+
return false;
|
|
1640
|
+
}
|
|
1641
|
+
else if (xfer instanceof Transformers_1.UnionInstantiationTransformer) {
|
|
1642
|
+
if (!(targetType instanceof Type_1.UnionType)) {
|
|
1643
|
+
return Support_1.panic("Union instantiation transformer must produce a union type");
|
|
1644
|
+
}
|
|
1645
|
+
const maybeNullable = TypeUtils_1.nullableFromUnion(targetType);
|
|
1646
|
+
if (maybeNullable !== null) {
|
|
1647
|
+
emitFinish(variable);
|
|
1648
|
+
}
|
|
1649
|
+
else {
|
|
1650
|
+
const unionName = this.nameForNamedType(targetType);
|
|
1651
|
+
let initializer;
|
|
1652
|
+
if (xfer.sourceType.kind === "null") {
|
|
1653
|
+
initializer = " ";
|
|
1654
|
+
}
|
|
1655
|
+
else {
|
|
1656
|
+
const memberName = this.nameForUnionMember(targetType, xfer.sourceType);
|
|
1657
|
+
initializer = [" ", memberName, " = ", variable, " "];
|
|
1658
|
+
}
|
|
1659
|
+
emitFinish(["new ", unionName, " {", initializer, "}"]);
|
|
1660
|
+
}
|
|
1661
|
+
return true;
|
|
1662
|
+
}
|
|
1663
|
+
else {
|
|
1664
|
+
return Support_1.panic("Unknown transformer");
|
|
1665
|
+
}
|
|
1666
|
+
return false;
|
|
1667
|
+
}
|
|
1668
|
+
emitTransformation(converterName, t) {
|
|
1669
|
+
const xf = Support_1.defined(Transformers_1.transformationForType(t));
|
|
1670
|
+
const reverse = xf.reverse;
|
|
1671
|
+
const targetType = xf.targetType;
|
|
1672
|
+
const xfer = xf.transformer;
|
|
1673
|
+
const csType = this.csType(targetType);
|
|
1674
|
+
// const haveNullable = isValueType(targetType);
|
|
1675
|
+
// if (haveNullable) {
|
|
1676
|
+
// converterName = ['Nullable', converterName];
|
|
1677
|
+
// csType = [csType, "?"];
|
|
1678
|
+
// }
|
|
1679
|
+
this.emitType(undefined, AccessModifier.Internal, "class", converterName, ["JsonConverter<", csType, ">"], () => {
|
|
1680
|
+
let canConvertExpr = ["t == typeof(", csType, ")"];
|
|
1681
|
+
this.emitCanConvert(canConvertExpr);
|
|
1682
|
+
this.ensureBlankLine();
|
|
1683
|
+
this.emitReadJson(() => {
|
|
1684
|
+
// FIXME: It's unsatisfying that we need this. The reason is that we not
|
|
1685
|
+
// only match T, but also T?. If we didn't, then the T in T? would not be
|
|
1686
|
+
// deserialized with our converter but with the default one. Can we check
|
|
1687
|
+
// whether the type is a nullable?
|
|
1688
|
+
// FIXME: This could duplicate one of the cases handled below in
|
|
1689
|
+
// `emitDecodeTransformer`.
|
|
1690
|
+
// if (haveNullable && !(targetType instanceof UnionType)) {
|
|
1691
|
+
// this.emitLine("if (reader.TokenType == JsonTokenType.Null) return null;");
|
|
1692
|
+
// }
|
|
1693
|
+
const allHandled = this.emitDecodeTransformer(xfer, targetType, v => this.emitLine("return ", v, ";"));
|
|
1694
|
+
if (!allHandled) {
|
|
1695
|
+
this.emitThrow(['"Cannot unmarshal type ', csType, '"']);
|
|
1696
|
+
}
|
|
1697
|
+
}, csType);
|
|
1698
|
+
this.ensureBlankLine();
|
|
1699
|
+
this.emitWriteJson("value", () => {
|
|
1700
|
+
// FIXME: See above.
|
|
1701
|
+
// if (haveNullable && !(targetType instanceof UnionType)) {
|
|
1702
|
+
// this.emitLine("if (value == null)");
|
|
1703
|
+
// this.emitBlock(() => {
|
|
1704
|
+
// this.emitLine("writer.WriteNullValue();");
|
|
1705
|
+
// this.emitLine("return;");
|
|
1706
|
+
// });
|
|
1707
|
+
// }
|
|
1708
|
+
const allHandled = this.emitTransformer("value", reverse.transformer, reverse.targetType, () => this.emitLine("return;"));
|
|
1709
|
+
if (!allHandled) {
|
|
1710
|
+
this.emitThrow(['"Cannot marshal type ', csType, '"']);
|
|
1711
|
+
}
|
|
1712
|
+
}, csType);
|
|
1713
|
+
this.ensureBlankLine();
|
|
1714
|
+
this.emitLine("public static readonly ", converterName, " Singleton = new ", converterName, "();");
|
|
1715
|
+
});
|
|
1716
|
+
}
|
|
1717
|
+
emitRequiredHelpers() {
|
|
1718
|
+
if (this._needHelpers) {
|
|
1719
|
+
this.forEachTopLevel("leading-and-interposing", (t, n) => this.emitFromJsonForTopLevel(t, n));
|
|
1720
|
+
this.ensureBlankLine();
|
|
1721
|
+
this.emitSerializeClass();
|
|
1722
|
+
}
|
|
1723
|
+
if (this._needHelpers || (this._needAttributes && (this.haveNamedUnions || this.haveEnums))) {
|
|
1724
|
+
this.ensureBlankLine();
|
|
1725
|
+
this.emitConverterClass();
|
|
1726
|
+
this.forEachTransformation("leading-and-interposing", (n, t) => this.emitTransformation(n, t));
|
|
1727
|
+
this.emitMultiline(`
|
|
1728
|
+
public class DateOnlyConverter : JsonConverter<DateOnly>
|
|
1729
|
+
{
|
|
1730
|
+
private readonly string serializationFormat;
|
|
1731
|
+
public DateOnlyConverter() : this(null) { }
|
|
1732
|
+
|
|
1733
|
+
public DateOnlyConverter(string? serializationFormat)
|
|
1734
|
+
{
|
|
1735
|
+
this.serializationFormat = serializationFormat ?? "yyyy-MM-dd";
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
1739
|
+
{
|
|
1740
|
+
var value = reader.GetString();
|
|
1741
|
+
return DateOnly.Parse(value!);
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1744
|
+
public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
|
|
1745
|
+
=> writer.WriteStringValue(value.ToString(serializationFormat));
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
public class TimeOnlyConverter : JsonConverter<TimeOnly>
|
|
1749
|
+
{
|
|
1750
|
+
private readonly string serializationFormat;
|
|
1751
|
+
|
|
1752
|
+
public TimeOnlyConverter() : this(null) { }
|
|
1753
|
+
|
|
1754
|
+
public TimeOnlyConverter(string? serializationFormat)
|
|
1755
|
+
{
|
|
1756
|
+
this.serializationFormat = serializationFormat ?? "HH:mm:ss.fff";
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
1760
|
+
{
|
|
1761
|
+
var value = reader.GetString();
|
|
1762
|
+
return TimeOnly.Parse(value!);
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options)
|
|
1766
|
+
=> writer.WriteStringValue(value.ToString(serializationFormat));
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
internal class IsoDateTimeOffsetConverter : JsonConverter<DateTimeOffset>
|
|
1770
|
+
{
|
|
1771
|
+
public override bool CanConvert(Type t) => t == typeof(DateTimeOffset);
|
|
1772
|
+
|
|
1773
|
+
private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
|
|
1774
|
+
|
|
1775
|
+
private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
|
|
1776
|
+
private string? _dateTimeFormat;
|
|
1777
|
+
private CultureInfo? _culture;
|
|
1778
|
+
|
|
1779
|
+
public DateTimeStyles DateTimeStyles
|
|
1780
|
+
{
|
|
1781
|
+
get => _dateTimeStyles;
|
|
1782
|
+
set => _dateTimeStyles = value;
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
public string? DateTimeFormat
|
|
1786
|
+
{
|
|
1787
|
+
get => _dateTimeFormat ?? string.Empty;
|
|
1788
|
+
set => _dateTimeFormat = (string.IsNullOrEmpty(value)) ? null : value;
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
public CultureInfo Culture
|
|
1792
|
+
{
|
|
1793
|
+
get => _culture ?? CultureInfo.CurrentCulture;
|
|
1794
|
+
set => _culture = value;
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
|
|
1798
|
+
{
|
|
1799
|
+
string text;
|
|
1800
|
+
|
|
1801
|
+
|
|
1802
|
+
if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
|
|
1803
|
+
|| (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
|
|
1804
|
+
{
|
|
1805
|
+
value = value.ToUniversalTime();
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
text = value.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
|
|
1809
|
+
|
|
1810
|
+
writer.WriteStringValue(text);
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
1814
|
+
{
|
|
1815
|
+
string? dateText = reader.GetString();
|
|
1816
|
+
|
|
1817
|
+
if (string.IsNullOrEmpty(dateText) == false)
|
|
1818
|
+
{
|
|
1819
|
+
if (!string.IsNullOrEmpty(_dateTimeFormat))
|
|
1820
|
+
{
|
|
1821
|
+
return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
|
|
1822
|
+
}
|
|
1823
|
+
else
|
|
1824
|
+
{
|
|
1825
|
+
return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
else
|
|
1829
|
+
{
|
|
1830
|
+
return default(DateTimeOffset);
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
|
|
1835
|
+
public static readonly IsoDateTimeOffsetConverter Singleton = new IsoDateTimeOffsetConverter();
|
|
1836
|
+
}`);
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
needNamespace() {
|
|
1840
|
+
return this._needNamespaces;
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
exports.SystemTextJsonCSharpRenderer = SystemTextJsonCSharpRenderer;
|
package/dist/language/Rust.js
CHANGED
|
@@ -270,7 +270,7 @@ class RustRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
270
270
|
this.emitCommentLines(this.leadingComments);
|
|
271
271
|
return;
|
|
272
272
|
}
|
|
273
|
-
const topLevelName = Support_1.defined(collection_utils_1.mapFirst(this.topLevels));
|
|
273
|
+
const topLevelName = Support_1.defined(collection_utils_1.mapFirst(this.topLevels)).getCombinedName();
|
|
274
274
|
this.emitMultiline(`// Example code that deserializes and serializes the model.
|
|
275
275
|
// extern crate serde;
|
|
276
276
|
// #[macro_use]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quicktype-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "The quicktype engine as a library",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -45,6 +45,6 @@
|
|
|
45
45
|
"fs": false
|
|
46
46
|
},
|
|
47
47
|
"config": {
|
|
48
|
-
"commit": "
|
|
48
|
+
"commit": "3118cbe3f215406f704558a1e5e07e5160b5fcff"
|
|
49
49
|
}
|
|
50
50
|
}
|