quicktype 17.0.6 → 18.0.1
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/cli/CompressedJSONFromStream.js +26 -38
- package/dist/cli/GraphQLIntrospection.js +33 -41
- package/dist/cli/TypeSource.d.ts +1 -1
- package/dist/cli/URLGrammar.js +4 -3
- package/dist/cli/index.js +363 -364
- package/dist/quicktype-core/Annotation.js +2 -0
- package/dist/quicktype-core/ConvenienceRenderer.d.ts +17 -17
- package/dist/quicktype-core/ConvenienceRenderer.js +104 -81
- package/dist/quicktype-core/DateTime.js +1 -0
- package/dist/quicktype-core/DeclarationIR.d.ts +1 -1
- package/dist/quicktype-core/DeclarationIR.js +13 -10
- package/dist/quicktype-core/EncodedMarkovChain.js +1 -0
- package/dist/quicktype-core/GatherNames.js +47 -25
- package/dist/quicktype-core/Graph.d.ts +2 -2
- package/dist/quicktype-core/Graph.js +23 -19
- package/dist/quicktype-core/GraphRewriting.d.ts +2 -2
- package/dist/quicktype-core/GraphRewriting.js +65 -54
- package/dist/quicktype-core/MakeTransformations.js +23 -22
- package/dist/quicktype-core/MarkovChain.d.ts +3 -3
- package/dist/quicktype-core/MarkovChain.js +9 -8
- package/dist/quicktype-core/Messages.d.ts +3 -3
- package/dist/quicktype-core/Messages.js +8 -3
- package/dist/quicktype-core/Naming.d.ts +11 -11
- package/dist/quicktype-core/Naming.js +76 -61
- package/dist/quicktype-core/Renderer.d.ts +6 -6
- package/dist/quicktype-core/Renderer.js +34 -17
- package/dist/quicktype-core/RendererOptions.d.ts +5 -5
- package/dist/quicktype-core/RendererOptions.js +6 -3
- package/dist/quicktype-core/Run.d.ts +9 -9
- package/dist/quicktype-core/Run.js +72 -67
- package/dist/quicktype-core/Source.d.ts +3 -3
- package/dist/quicktype-core/Source.js +19 -18
- package/dist/quicktype-core/TargetLanguage.d.ts +10 -10
- package/dist/quicktype-core/TargetLanguage.js +6 -2
- package/dist/quicktype-core/Transformers.d.ts +25 -25
- package/dist/quicktype-core/Transformers.js +94 -66
- package/dist/quicktype-core/Type.d.ts +41 -43
- package/dist/quicktype-core/Type.js +96 -71
- package/dist/quicktype-core/TypeBuilder.d.ts +2 -2
- package/dist/quicktype-core/TypeBuilder.js +53 -47
- package/dist/quicktype-core/TypeGraph.d.ts +4 -4
- package/dist/quicktype-core/TypeGraph.js +49 -40
- package/dist/quicktype-core/TypeUtils.d.ts +2 -2
- package/dist/quicktype-core/TypeUtils.js +23 -22
- package/dist/quicktype-core/UnifyClasses.js +16 -12
- package/dist/quicktype-core/UnionBuilder.d.ts +3 -3
- package/dist/quicktype-core/UnionBuilder.js +33 -30
- package/dist/quicktype-core/attributes/AccessorNames.d.ts +2 -2
- package/dist/quicktype-core/attributes/AccessorNames.js +18 -17
- package/dist/quicktype-core/attributes/Constraints.d.ts +3 -3
- package/dist/quicktype-core/attributes/Constraints.js +8 -4
- package/dist/quicktype-core/attributes/Description.js +6 -5
- package/dist/quicktype-core/attributes/EnumValues.js +4 -3
- package/dist/quicktype-core/attributes/StringTypes.d.ts +1 -1
- package/dist/quicktype-core/attributes/StringTypes.js +24 -21
- package/dist/quicktype-core/attributes/TypeAttributes.d.ts +3 -3
- package/dist/quicktype-core/attributes/TypeAttributes.js +12 -10
- package/dist/quicktype-core/attributes/TypeNames.d.ts +9 -9
- package/dist/quicktype-core/attributes/TypeNames.js +49 -21
- package/dist/quicktype-core/attributes/URIAttributes.d.ts +1 -1
- package/dist/quicktype-core/attributes/URIAttributes.js +10 -6
- package/dist/quicktype-core/index.js +128 -125
- package/dist/quicktype-core/input/CompressedJSON.d.ts +7 -7
- package/dist/quicktype-core/input/CompressedJSON.js +49 -54
- package/dist/quicktype-core/input/FetchingJSONSchemaStore.js +5 -13
- package/dist/quicktype-core/input/Inference.d.ts +2 -2
- package/dist/quicktype-core/input/Inference.js +25 -17
- package/dist/quicktype-core/input/Inputs.d.ts +2 -2
- package/dist/quicktype-core/input/Inputs.js +38 -54
- package/dist/quicktype-core/input/JSONSchemaInput.d.ts +11 -11
- package/dist/quicktype-core/input/JSONSchemaInput.js +503 -523
- package/dist/quicktype-core/input/JSONSchemaStore.d.ts +1 -1
- package/dist/quicktype-core/input/JSONSchemaStore.js +24 -35
- package/dist/quicktype-core/input/PostmanCollection.js +2 -1
- package/dist/quicktype-core/input/io/NodeIO.js +55 -44
- package/dist/quicktype-core/input/io/get-stream/index.js +6 -2
- package/dist/quicktype-core/language/All.js +3 -2
- package/dist/quicktype-core/language/CPlusPlus.d.ts +8 -8
- package/dist/quicktype-core/language/CPlusPlus.js +185 -151
- package/dist/quicktype-core/language/CSharp.d.ts +7 -7
- package/dist/quicktype-core/language/CSharp.js +82 -72
- package/dist/quicktype-core/language/Crystal.d.ts +2 -2
- package/dist/quicktype-core/language/Crystal.js +18 -17
- package/dist/quicktype-core/language/Dart.d.ts +4 -4
- package/dist/quicktype-core/language/Dart.js +36 -34
- package/dist/quicktype-core/language/Elm.d.ts +6 -6
- package/dist/quicktype-core/language/Elm.js +47 -45
- package/dist/quicktype-core/language/Golang.d.ts +4 -4
- package/dist/quicktype-core/language/Golang.js +23 -20
- package/dist/quicktype-core/language/Haskell.d.ts +5 -5
- package/dist/quicktype-core/language/Haskell.js +25 -23
- package/dist/quicktype-core/language/JSONSchema.d.ts +3 -3
- package/dist/quicktype-core/language/JSONSchema.js +17 -16
- package/dist/quicktype-core/language/Java.d.ts +2 -2
- package/dist/quicktype-core/language/Java.js +97 -97
- package/dist/quicktype-core/language/JavaScript.d.ts +7 -7
- package/dist/quicktype-core/language/JavaScript.js +20 -18
- package/dist/quicktype-core/language/JavaScriptPropTypes.js +15 -13
- package/dist/quicktype-core/language/JavaScriptUnicodeMaps.js +12 -11
- package/dist/quicktype-core/language/Kotlin.d.ts +2 -2
- package/dist/quicktype-core/language/Kotlin.js +39 -37
- package/dist/quicktype-core/language/Objective-C.d.ts +3 -3
- package/dist/quicktype-core/language/Objective-C.js +45 -41
- package/dist/quicktype-core/language/Php.d.ts +2 -2
- package/dist/quicktype-core/language/Php.js +66 -41
- package/dist/quicktype-core/language/Pike.d.ts +1 -1
- package/dist/quicktype-core/language/Pike.js +18 -17
- package/dist/quicktype-core/language/Python.d.ts +8 -8
- package/dist/quicktype-core/language/Python.js +63 -64
- package/dist/quicktype-core/language/Rust.d.ts +2 -2
- package/dist/quicktype-core/language/Rust.js +21 -19
- package/dist/quicktype-core/language/Swift.d.ts +7 -7
- package/dist/quicktype-core/language/Swift.js +568 -565
- package/dist/quicktype-core/language/TypeScriptFlow.d.ts +7 -7
- package/dist/quicktype-core/language/TypeScriptFlow.js +28 -26
- package/dist/quicktype-core/language/ruby/index.d.ts +4 -4
- package/dist/quicktype-core/language/ruby/index.js +49 -24
- package/dist/quicktype-core/language/ruby/keywords.js +1 -0
- package/dist/quicktype-core/rewrites/CombineClasses.js +9 -8
- package/dist/quicktype-core/rewrites/ExpandStrings.d.ts +1 -1
- package/dist/quicktype-core/rewrites/ExpandStrings.js +18 -17
- package/dist/quicktype-core/rewrites/FlattenStrings.js +7 -6
- package/dist/quicktype-core/rewrites/FlattenUnions.js +9 -8
- package/dist/quicktype-core/rewrites/InferMaps.js +11 -10
- package/dist/quicktype-core/rewrites/ReplaceObjectType.js +8 -7
- package/dist/quicktype-core/rewrites/ResolveIntersections.js +68 -67
- package/dist/quicktype-core/support/Acronyms.js +3 -1
- package/dist/quicktype-core/support/Chance.js +10 -0
- package/dist/quicktype-core/support/Converters.js +1 -0
- package/dist/quicktype-core/support/Strings.d.ts +4 -4
- package/dist/quicktype-core/support/Strings.js +17 -16
- package/dist/quicktype-core/support/Support.d.ts +1 -1
- package/dist/quicktype-core/support/Support.js +30 -6
- package/dist/quicktype-graphql-input/GraphQLSchema.d.ts +4 -4
- package/dist/quicktype-graphql-input/GraphQLSchema.js +1 -0
- package/dist/quicktype-graphql-input/index.d.ts +1 -1
- package/dist/quicktype-graphql-input/index.js +229 -212
- package/dist/quicktype-typescript-input/index.js +28 -4
- package/package.json +24 -20
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SwiftRenderer = exports.SwiftTargetLanguage = exports.swiftOptions = void 0;
|
|
3
4
|
const collection_utils_1 = require("collection-utils");
|
|
4
5
|
const Support_1 = require("../support/Support");
|
|
5
6
|
const TargetLanguage_1 = require("../TargetLanguage");
|
|
@@ -26,7 +27,7 @@ exports.swiftOptions = {
|
|
|
26
27
|
["class", true]
|
|
27
28
|
]),
|
|
28
29
|
mutableProperties: new RendererOptions_1.BooleanOption("mutable-properties", "Use var instead of let for object properties", false),
|
|
29
|
-
acronymStyle: Acronyms_1.acronymOption(Acronyms_1.AcronymStyleOptions.Pascal),
|
|
30
|
+
acronymStyle: (0, Acronyms_1.acronymOption)(Acronyms_1.AcronymStyleOptions.Pascal),
|
|
30
31
|
dense: new RendererOptions_1.EnumOption("density", "Code density", [
|
|
31
32
|
["dense", true],
|
|
32
33
|
["normal", false]
|
|
@@ -98,7 +99,7 @@ class SwiftTargetLanguage extends TargetLanguage_1.TargetLanguage {
|
|
|
98
99
|
return true;
|
|
99
100
|
}
|
|
100
101
|
makeRenderer(renderContext, untypedOptionValues) {
|
|
101
|
-
return new SwiftRenderer(this, renderContext, RendererOptions_1.getOptionValues(exports.swiftOptions, untypedOptionValues));
|
|
102
|
+
return new SwiftRenderer(this, renderContext, (0, RendererOptions_1.getOptionValues)(exports.swiftOptions, untypedOptionValues));
|
|
102
103
|
}
|
|
103
104
|
get dateTimeRecognizer() {
|
|
104
105
|
return new SwiftDateTimeRecognizer();
|
|
@@ -207,485 +208,193 @@ const keywords = [
|
|
|
207
208
|
"jsonData"
|
|
208
209
|
];
|
|
209
210
|
function isPartCharacter(codePoint) {
|
|
210
|
-
return Strings_1.isLetterOrUnderscore(codePoint) || Strings_1.isNumeric(codePoint);
|
|
211
|
+
return (0, Strings_1.isLetterOrUnderscore)(codePoint) || (0, Strings_1.isNumeric)(codePoint);
|
|
211
212
|
}
|
|
212
213
|
function isStartCharacter(codePoint) {
|
|
213
|
-
return isPartCharacter(codePoint) && !Strings_1.isDigit(codePoint);
|
|
214
|
+
return isPartCharacter(codePoint) && !(0, Strings_1.isDigit)(codePoint);
|
|
214
215
|
}
|
|
215
|
-
const legalizeName = Strings_1.legalizeCharacters(isPartCharacter);
|
|
216
|
+
const legalizeName = (0, Strings_1.legalizeCharacters)(isPartCharacter);
|
|
216
217
|
function swiftNameStyle(prefix, isUpper, original, acronymsStyle = Strings_1.allUpperWordStyle) {
|
|
217
|
-
const words = Strings_1.splitIntoWords(original);
|
|
218
|
-
const combined = Strings_1.combineWords(words, legalizeName, isUpper ? Strings_1.firstUpperWordStyle : Strings_1.allLowerWordStyle, Strings_1.firstUpperWordStyle, isUpper ? Strings_1.allUpperWordStyle : Strings_1.allLowerWordStyle, acronymsStyle, "", isStartCharacter);
|
|
219
|
-
return Strings_1.addPrefixIfNecessary(prefix, combined);
|
|
218
|
+
const words = (0, Strings_1.splitIntoWords)(original);
|
|
219
|
+
const combined = (0, Strings_1.combineWords)(words, legalizeName, isUpper ? Strings_1.firstUpperWordStyle : Strings_1.allLowerWordStyle, Strings_1.firstUpperWordStyle, isUpper ? Strings_1.allUpperWordStyle : Strings_1.allLowerWordStyle, acronymsStyle, "", isStartCharacter);
|
|
220
|
+
return (0, Strings_1.addPrefixIfNecessary)(prefix, combined);
|
|
220
221
|
}
|
|
221
222
|
function unicodeEscape(codePoint) {
|
|
222
|
-
return "\\u{" + Strings_1.intToHex(codePoint, 0) + "}";
|
|
223
|
+
return "\\u{" + (0, Strings_1.intToHex)(codePoint, 0) + "}";
|
|
223
224
|
}
|
|
224
|
-
const stringEscape = Strings_1.utf32ConcatMap(Strings_1.escapeNonPrintableMapper(Strings_1.isPrintable, unicodeEscape));
|
|
225
|
+
const stringEscape = (0, Strings_1.utf32ConcatMap)((0, Strings_1.escapeNonPrintableMapper)(Strings_1.isPrintable, unicodeEscape));
|
|
225
226
|
class SwiftRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
227
|
+
_options;
|
|
228
|
+
_currentFilename;
|
|
229
|
+
_needAny = false;
|
|
230
|
+
_needNull = false;
|
|
226
231
|
constructor(targetLanguage, renderContext, _options) {
|
|
227
232
|
super(targetLanguage, renderContext);
|
|
228
233
|
this._options = _options;
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
this.
|
|
232
|
-
|
|
233
|
-
this.emitLineOnce("import Foundation");
|
|
234
|
-
this.forEachTopLevel("leading", (t, name) => this.renderTopLevelAlias(t, name), t => this.namedTypeToNameForTopLevel(t) === undefined);
|
|
235
|
-
if (this._options.convenienceInitializers) {
|
|
236
|
-
this.ensureBlankLine();
|
|
237
|
-
this.forEachTopLevel("leading-and-interposing", (t, name) => this.emitTopLevelMapAndArrayConvenienceInitializerExtensions(t, name));
|
|
238
|
-
}
|
|
239
|
-
if ((!this._options.justTypes && this._options.convenienceInitializers) || this._options.alamofire) {
|
|
240
|
-
this.ensureBlankLine();
|
|
241
|
-
this.emitMark("Helper functions for creating encoders and decoders", true);
|
|
242
|
-
this.ensureBlankLine();
|
|
243
|
-
this.emitNewEncoderDecoder();
|
|
244
|
-
}
|
|
245
|
-
if (this._options.alamofire) {
|
|
246
|
-
this.ensureBlankLine();
|
|
247
|
-
this.emitMark("Alamofire response handlers", true);
|
|
248
|
-
this.ensureBlankLine();
|
|
249
|
-
this.emitAlamofireExtension();
|
|
250
|
-
}
|
|
251
|
-
// This assumes that this method is called after declarations
|
|
252
|
-
// are emitted.
|
|
253
|
-
if (this._needAny || this._needNull) {
|
|
254
|
-
this.ensureBlankLine();
|
|
255
|
-
this.emitMark("Encode/decode helpers", true);
|
|
256
|
-
this.ensureBlankLine();
|
|
257
|
-
if (this._options.objcSupport) {
|
|
258
|
-
this.emitLine(this.objcMembersDeclaration, this.accessLevel, "class JSONNull: NSObject, Codable {");
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
this.emitLine(this.accessLevel, "class JSONNull: Codable, Hashable {");
|
|
262
|
-
}
|
|
263
|
-
this.ensureBlankLine();
|
|
264
|
-
this.emitMultiline(` public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
|
|
265
|
-
return true
|
|
266
|
-
}`);
|
|
267
|
-
if (this._options.objcSupport === false) {
|
|
268
|
-
this.ensureBlankLine();
|
|
269
|
-
this.emitMultiline(` public var hashValue: Int {
|
|
270
|
-
return 0
|
|
271
|
-
}`);
|
|
272
|
-
if (this._options.swift5Support) {
|
|
273
|
-
this.ensureBlankLine();
|
|
274
|
-
this.emitMultiline(` public func hash(into hasher: inout Hasher) {
|
|
275
|
-
// No-op
|
|
276
|
-
}`);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
this.ensureBlankLine();
|
|
280
|
-
if (this._options.objcSupport) {
|
|
281
|
-
this.emitItem(" override ");
|
|
282
|
-
}
|
|
283
|
-
else {
|
|
284
|
-
this.emitItem(" ");
|
|
285
|
-
}
|
|
286
|
-
this.emitMultiline(`public init() {}
|
|
287
|
-
|
|
288
|
-
public required init(from decoder: Decoder) throws {
|
|
289
|
-
let container = try decoder.singleValueContainer()
|
|
290
|
-
if !container.decodeNil() {
|
|
291
|
-
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
|
|
234
|
+
}
|
|
235
|
+
forbiddenNamesForGlobalNamespace() {
|
|
236
|
+
if (this._options.alamofire) {
|
|
237
|
+
return ["DataRequest", ...keywords];
|
|
292
238
|
}
|
|
239
|
+
return keywords;
|
|
293
240
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
var container = encoder.singleValueContainer()
|
|
297
|
-
try container.encodeNil()
|
|
241
|
+
forbiddenForObjectProperties(_c, _classNamed) {
|
|
242
|
+
return { names: ["fromURL", "json"], includeGlobalForbidden: true };
|
|
298
243
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (this._needAny) {
|
|
302
|
-
this.ensureBlankLine();
|
|
303
|
-
this.emitMultiline(`class JSONCodingKey: CodingKey {
|
|
304
|
-
let key: String
|
|
305
|
-
|
|
306
|
-
required init?(intValue: Int) {
|
|
307
|
-
return nil
|
|
244
|
+
forbiddenForEnumCases(_e, _enumName) {
|
|
245
|
+
return { names: [], includeGlobalForbidden: true };
|
|
308
246
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
key = stringValue
|
|
247
|
+
forbiddenForUnionMembers(_u, _unionName) {
|
|
248
|
+
return { names: [], includeGlobalForbidden: true };
|
|
312
249
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
return nil
|
|
250
|
+
makeNamedTypeNamer() {
|
|
251
|
+
return (0, Naming_1.funPrefixNamer)("upper", s => swiftNameStyle(this._options.namedTypePrefix, true, s, (0, Acronyms_1.acronymStyle)(this._options.acronymStyle)));
|
|
316
252
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
return key
|
|
253
|
+
namerForObjectProperty() {
|
|
254
|
+
return this.lowerNamingFunction;
|
|
320
255
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
if (this._options.objcSupport) {
|
|
324
|
-
this.emitLine(this.objcMembersDeclaration, this.accessLevel, "class JSONAny: NSObject, Codable {");
|
|
325
|
-
}
|
|
326
|
-
else {
|
|
327
|
-
this.emitLine(this.accessLevel, "class JSONAny: Codable {");
|
|
328
|
-
}
|
|
329
|
-
this.ensureBlankLine();
|
|
330
|
-
this.emitMultiline(` ${this.accessLevel}let value: Any
|
|
331
|
-
|
|
332
|
-
static func decodingError(forCodingPath codingPath: [CodingKey]) -> DecodingError {
|
|
333
|
-
let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Cannot decode JSONAny")
|
|
334
|
-
return DecodingError.typeMismatch(JSONAny.self, context)
|
|
256
|
+
makeUnionMemberNamer() {
|
|
257
|
+
return this.lowerNamingFunction;
|
|
335
258
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
let context = EncodingError.Context(codingPath: codingPath, debugDescription: "Cannot encode JSONAny")
|
|
339
|
-
return EncodingError.invalidValue(value, context)
|
|
259
|
+
makeEnumCaseNamer() {
|
|
260
|
+
return this.lowerNamingFunction;
|
|
340
261
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
return value
|
|
345
|
-
}
|
|
346
|
-
if let value = try? container.decode(Int64.self) {
|
|
347
|
-
return value
|
|
348
|
-
}
|
|
349
|
-
if let value = try? container.decode(Double.self) {
|
|
350
|
-
return value
|
|
351
|
-
}
|
|
352
|
-
if let value = try? container.decode(String.self) {
|
|
353
|
-
return value
|
|
354
|
-
}
|
|
355
|
-
if container.decodeNil() {
|
|
356
|
-
return JSONNull()
|
|
357
|
-
}
|
|
358
|
-
throw decodingError(forCodingPath: container.codingPath)
|
|
262
|
+
isImplicitCycleBreaker(t) {
|
|
263
|
+
const kind = t.kind;
|
|
264
|
+
return kind === "array" || kind === "map";
|
|
359
265
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
266
|
+
emitDescriptionBlock(lines) {
|
|
267
|
+
this.emitCommentLines(lines, "/// ");
|
|
268
|
+
}
|
|
269
|
+
emitBlock(line, f) {
|
|
270
|
+
this.emitLine(line, " {");
|
|
271
|
+
this.indent(f);
|
|
272
|
+
this.emitLine("}");
|
|
273
|
+
}
|
|
274
|
+
emitBlockWithAccess(line, f) {
|
|
275
|
+
this.emitBlock([this.accessLevel, line], f);
|
|
276
|
+
}
|
|
277
|
+
justTypesCase(justTypes, notJustTypes) {
|
|
278
|
+
if (this._options.justTypes)
|
|
279
|
+
return justTypes;
|
|
280
|
+
else
|
|
281
|
+
return notJustTypes;
|
|
282
|
+
}
|
|
283
|
+
get lowerNamingFunction() {
|
|
284
|
+
return (0, Naming_1.funPrefixNamer)("lower", s => swiftNameStyle("", false, s, (0, Acronyms_1.acronymStyle)(this._options.acronymStyle)));
|
|
285
|
+
}
|
|
286
|
+
swiftPropertyType(p) {
|
|
287
|
+
if (p.isOptional || (this._options.optionalEnums && p.type.kind === "enum")) {
|
|
288
|
+
return [this.swiftType(p.type, true, true), "?"];
|
|
370
289
|
}
|
|
371
|
-
|
|
372
|
-
return
|
|
290
|
+
else {
|
|
291
|
+
return this.swiftType(p.type, true);
|
|
373
292
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
293
|
+
}
|
|
294
|
+
swiftType(t, withIssues = false, noOptional = false) {
|
|
295
|
+
const optional = noOptional ? "" : "?";
|
|
296
|
+
return (0, TypeUtils_1.matchType)(t, _anyType => {
|
|
297
|
+
this._needAny = true;
|
|
298
|
+
return (0, Source_1.maybeAnnotated)(withIssues, Annotation_1.anyTypeIssueAnnotation, this.justTypesCase(["Any", optional], "JSONAny"));
|
|
299
|
+
}, _nullType => {
|
|
300
|
+
this._needNull = true;
|
|
301
|
+
return (0, Source_1.maybeAnnotated)(withIssues, Annotation_1.nullTypeIssueAnnotation, this.justTypesCase("NSNull", ["JSONNull", optional]));
|
|
302
|
+
}, _boolType => "Bool", _integerType => "Int", _doubleType => "Double", _stringType => "String", arrayType => ["[", this.swiftType(arrayType.items, withIssues), "]"], classType => this.nameForNamedType(classType), mapType => ["[String: ", this.swiftType(mapType.values, withIssues), "]"], enumType => this.nameForNamedType(enumType), unionType => {
|
|
303
|
+
const nullable = (0, TypeUtils_1.nullableFromUnion)(unionType);
|
|
304
|
+
if (nullable !== null)
|
|
305
|
+
return [this.swiftType(nullable, withIssues), optional];
|
|
306
|
+
return this.nameForNamedType(unionType);
|
|
307
|
+
}, transformedStringType => {
|
|
308
|
+
if (transformedStringType.kind === "date-time") {
|
|
309
|
+
return "Date";
|
|
377
310
|
}
|
|
311
|
+
else {
|
|
312
|
+
return (0, Support_2.panic)(`Transformed string type ${transformedStringType.kind} not supported`);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
proposedUnionMemberNameForTypeKind(kind) {
|
|
317
|
+
if (kind === "enum") {
|
|
318
|
+
return "enumeration";
|
|
378
319
|
}
|
|
379
|
-
if
|
|
380
|
-
return
|
|
381
|
-
}
|
|
382
|
-
if var container = try? container.nestedContainer(keyedBy: JSONCodingKey.self) {
|
|
383
|
-
return try decodeDictionary(from: &container)
|
|
320
|
+
if (kind === "union") {
|
|
321
|
+
return "one_of";
|
|
384
322
|
}
|
|
385
|
-
|
|
323
|
+
return null;
|
|
386
324
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
325
|
+
renderSingleFileHeaderComments() {
|
|
326
|
+
this.emitLineOnce("// This file was generated from JSON Schema using quicktype, do not modify it directly.");
|
|
327
|
+
this.emitLineOnce("// To parse the JSON, add this file to your project and do:");
|
|
328
|
+
this.emitLineOnce("//");
|
|
329
|
+
this.forEachTopLevel("none", (t, topLevelName) => {
|
|
330
|
+
if (this._options.convenienceInitializers && !(t instanceof Type_1.EnumType)) {
|
|
331
|
+
this.emitLineOnce("// let ", (0, Source_1.modifySource)(Strings_1.camelCase, topLevelName), " = try ", topLevelName, "(json)");
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
this.emitLineOnce("// let ", (0, Source_1.modifySource)(Strings_1.camelCase, topLevelName), " = ", "try? JSONDecoder().decode(", topLevelName, ".self, from: jsonData)");
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
renderHeader(type, name) {
|
|
339
|
+
if (this.leadingComments !== undefined) {
|
|
340
|
+
this.emitCommentLines(this.leadingComments);
|
|
391
341
|
}
|
|
392
|
-
if
|
|
393
|
-
|
|
342
|
+
else if (!this._options.justTypes) {
|
|
343
|
+
if (this._options.multiFileOutput) {
|
|
344
|
+
this.emitLineOnce("// This file was generated from JSON Schema using quicktype, do not modify it directly.");
|
|
345
|
+
this.emitLineOnce("// To parse the JSON, add this file to your project and do:");
|
|
346
|
+
this.emitLineOnce("//");
|
|
347
|
+
if (this._options.convenienceInitializers && !(type instanceof Type_1.EnumType)) {
|
|
348
|
+
this.emitLine("// let ", (0, Source_1.modifySource)(Strings_1.camelCase, name), " = try ", name, "(json)");
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
this.emitLine("// let ", (0, Source_1.modifySource)(Strings_1.camelCase, name), " = ", "try? newJSONDecoder().decode(", name, ".self, from: jsonData)");
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
if (this._options.alamofire) {
|
|
355
|
+
this.emitLine("//");
|
|
356
|
+
this.emitLine("// To parse values from Alamofire responses:");
|
|
357
|
+
this.emitLine("//");
|
|
358
|
+
this.emitLine("// Alamofire.request(url).response", name, " { response in");
|
|
359
|
+
this.emitLine("// if let ", (0, Source_1.modifySource)(Strings_1.camelCase, name), " = response.result.value {");
|
|
360
|
+
this.emitLine("// ...");
|
|
361
|
+
this.emitLine("// }");
|
|
362
|
+
this.emitLine("// }");
|
|
363
|
+
}
|
|
364
|
+
if (this._options.protocol.hashable || this._options.protocol.equatable) {
|
|
365
|
+
this.emitLine("//");
|
|
366
|
+
this.emitLine("// Hashable or Equatable:");
|
|
367
|
+
this.emitLine("// The compiler will not be able to synthesize the implementation of Hashable or Equatable");
|
|
368
|
+
this.emitLine("// for types that require the use of JSONAny, nor will the implementation of Hashable be");
|
|
369
|
+
this.emitLine("// synthesized for types that have collections (such as arrays or dictionaries).");
|
|
370
|
+
}
|
|
394
371
|
}
|
|
395
|
-
|
|
396
|
-
|
|
372
|
+
this.ensureBlankLine();
|
|
373
|
+
this.emitLineOnce("import Foundation");
|
|
374
|
+
if (!this._options.justTypes && this._options.alamofire) {
|
|
375
|
+
this.emitLineOnce("import Alamofire");
|
|
397
376
|
}
|
|
398
|
-
|
|
399
|
-
|
|
377
|
+
this.ensureBlankLine();
|
|
378
|
+
}
|
|
379
|
+
renderTopLevelAlias(t, name) {
|
|
380
|
+
this.emitLine(this.accessLevel, "typealias ", name, " = ", this.swiftType(t, true));
|
|
381
|
+
}
|
|
382
|
+
getProtocolsArray(_t, isClass) {
|
|
383
|
+
const protocols = [];
|
|
384
|
+
// [Michael Fey (@MrRooni), 2019-4-24] Technically NSObject isn't a "protocol" in this instance, but this felt like the best place to slot in this superclass declaration.
|
|
385
|
+
if (isClass && this._options.objcSupport) {
|
|
386
|
+
protocols.push("NSObject");
|
|
400
387
|
}
|
|
401
|
-
if
|
|
402
|
-
|
|
403
|
-
return JSONNull()
|
|
404
|
-
}
|
|
388
|
+
if (!this._options.justTypes) {
|
|
389
|
+
protocols.push("Codable");
|
|
405
390
|
}
|
|
406
|
-
if
|
|
407
|
-
|
|
391
|
+
if (this._options.protocol.hashable) {
|
|
392
|
+
protocols.push("Hashable");
|
|
408
393
|
}
|
|
409
|
-
if
|
|
410
|
-
|
|
394
|
+
if (this._options.protocol.equatable) {
|
|
395
|
+
protocols.push("Equatable");
|
|
411
396
|
}
|
|
412
|
-
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
static func decodeArray(from container: inout UnkeyedDecodingContainer) throws -> [Any] {
|
|
416
|
-
var arr: [Any] = []
|
|
417
|
-
while !container.isAtEnd {
|
|
418
|
-
let value = try decode(from: &container)
|
|
419
|
-
arr.append(value)
|
|
420
|
-
}
|
|
421
|
-
return arr
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
static func decodeDictionary(from container: inout KeyedDecodingContainer<JSONCodingKey>) throws -> [String: Any] {
|
|
425
|
-
var dict = [String: Any]()
|
|
426
|
-
for key in container.allKeys {
|
|
427
|
-
let value = try decode(from: &container, forKey: key)
|
|
428
|
-
dict[key.stringValue] = value
|
|
429
|
-
}
|
|
430
|
-
return dict
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
static func encode(to container: inout UnkeyedEncodingContainer, array: [Any]) throws {
|
|
434
|
-
for value in array {
|
|
435
|
-
if let value = value as? Bool {
|
|
436
|
-
try container.encode(value)
|
|
437
|
-
} else if let value = value as? Int64 {
|
|
438
|
-
try container.encode(value)
|
|
439
|
-
} else if let value = value as? Double {
|
|
440
|
-
try container.encode(value)
|
|
441
|
-
} else if let value = value as? String {
|
|
442
|
-
try container.encode(value)
|
|
443
|
-
} else if value is JSONNull {
|
|
444
|
-
try container.encodeNil()
|
|
445
|
-
} else if let value = value as? [Any] {
|
|
446
|
-
var container = container.nestedUnkeyedContainer()
|
|
447
|
-
try encode(to: &container, array: value)
|
|
448
|
-
} else if let value = value as? [String: Any] {
|
|
449
|
-
var container = container.nestedContainer(keyedBy: JSONCodingKey.self)
|
|
450
|
-
try encode(to: &container, dictionary: value)
|
|
451
|
-
} else {
|
|
452
|
-
throw encodingError(forValue: value, codingPath: container.codingPath)
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
static func encode(to container: inout KeyedEncodingContainer<JSONCodingKey>, dictionary: [String: Any]) throws {
|
|
458
|
-
for (key, value) in dictionary {
|
|
459
|
-
let key = JSONCodingKey(stringValue: key)!
|
|
460
|
-
if let value = value as? Bool {
|
|
461
|
-
try container.encode(value, forKey: key)
|
|
462
|
-
} else if let value = value as? Int64 {
|
|
463
|
-
try container.encode(value, forKey: key)
|
|
464
|
-
} else if let value = value as? Double {
|
|
465
|
-
try container.encode(value, forKey: key)
|
|
466
|
-
} else if let value = value as? String {
|
|
467
|
-
try container.encode(value, forKey: key)
|
|
468
|
-
} else if value is JSONNull {
|
|
469
|
-
try container.encodeNil(forKey: key)
|
|
470
|
-
} else if let value = value as? [Any] {
|
|
471
|
-
var container = container.nestedUnkeyedContainer(forKey: key)
|
|
472
|
-
try encode(to: &container, array: value)
|
|
473
|
-
} else if let value = value as? [String: Any] {
|
|
474
|
-
var container = container.nestedContainer(keyedBy: JSONCodingKey.self, forKey: key)
|
|
475
|
-
try encode(to: &container, dictionary: value)
|
|
476
|
-
} else {
|
|
477
|
-
throw encodingError(forValue: value, codingPath: container.codingPath)
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
static func encode(to container: inout SingleValueEncodingContainer, value: Any) throws {
|
|
483
|
-
if let value = value as? Bool {
|
|
484
|
-
try container.encode(value)
|
|
485
|
-
} else if let value = value as? Int64 {
|
|
486
|
-
try container.encode(value)
|
|
487
|
-
} else if let value = value as? Double {
|
|
488
|
-
try container.encode(value)
|
|
489
|
-
} else if let value = value as? String {
|
|
490
|
-
try container.encode(value)
|
|
491
|
-
} else if value is JSONNull {
|
|
492
|
-
try container.encodeNil()
|
|
493
|
-
} else {
|
|
494
|
-
throw encodingError(forValue: value, codingPath: container.codingPath)
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
public required init(from decoder: Decoder) throws {
|
|
499
|
-
if var arrayContainer = try? decoder.unkeyedContainer() {
|
|
500
|
-
self.value = try JSONAny.decodeArray(from: &arrayContainer)
|
|
501
|
-
} else if var container = try? decoder.container(keyedBy: JSONCodingKey.self) {
|
|
502
|
-
self.value = try JSONAny.decodeDictionary(from: &container)
|
|
503
|
-
} else {
|
|
504
|
-
let container = try decoder.singleValueContainer()
|
|
505
|
-
self.value = try JSONAny.decode(from: container)
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
public func encode(to encoder: Encoder) throws {
|
|
510
|
-
if let arr = self.value as? [Any] {
|
|
511
|
-
var container = encoder.unkeyedContainer()
|
|
512
|
-
try JSONAny.encode(to: &container, array: arr)
|
|
513
|
-
} else if let dict = self.value as? [String: Any] {
|
|
514
|
-
var container = encoder.container(keyedBy: JSONCodingKey.self)
|
|
515
|
-
try JSONAny.encode(to: &container, dictionary: dict)
|
|
516
|
-
} else {
|
|
517
|
-
var container = encoder.singleValueContainer()
|
|
518
|
-
try JSONAny.encode(to: &container, value: self.value)
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
}`);
|
|
522
|
-
}
|
|
523
|
-
this.endFile();
|
|
524
|
-
};
|
|
525
|
-
}
|
|
526
|
-
forbiddenNamesForGlobalNamespace() {
|
|
527
|
-
if (this._options.alamofire) {
|
|
528
|
-
return ["DataRequest", ...keywords];
|
|
529
|
-
}
|
|
530
|
-
return keywords;
|
|
531
|
-
}
|
|
532
|
-
forbiddenForObjectProperties(_c, _classNamed) {
|
|
533
|
-
return { names: ["fromURL", "json"], includeGlobalForbidden: true };
|
|
534
|
-
}
|
|
535
|
-
forbiddenForEnumCases(_e, _enumName) {
|
|
536
|
-
return { names: [], includeGlobalForbidden: true };
|
|
537
|
-
}
|
|
538
|
-
forbiddenForUnionMembers(_u, _unionName) {
|
|
539
|
-
return { names: [], includeGlobalForbidden: true };
|
|
540
|
-
}
|
|
541
|
-
makeNamedTypeNamer() {
|
|
542
|
-
return Naming_1.funPrefixNamer("upper", s => swiftNameStyle(this._options.namedTypePrefix, true, s, Acronyms_1.acronymStyle(this._options.acronymStyle)));
|
|
543
|
-
}
|
|
544
|
-
namerForObjectProperty() {
|
|
545
|
-
return this.lowerNamingFunction;
|
|
546
|
-
}
|
|
547
|
-
makeUnionMemberNamer() {
|
|
548
|
-
return this.lowerNamingFunction;
|
|
549
|
-
}
|
|
550
|
-
makeEnumCaseNamer() {
|
|
551
|
-
return this.lowerNamingFunction;
|
|
552
|
-
}
|
|
553
|
-
isImplicitCycleBreaker(t) {
|
|
554
|
-
const kind = t.kind;
|
|
555
|
-
return kind === "array" || kind === "map";
|
|
556
|
-
}
|
|
557
|
-
emitDescriptionBlock(lines) {
|
|
558
|
-
this.emitCommentLines(lines, "/// ");
|
|
559
|
-
}
|
|
560
|
-
emitBlock(line, f) {
|
|
561
|
-
this.emitLine(line, " {");
|
|
562
|
-
this.indent(f);
|
|
563
|
-
this.emitLine("}");
|
|
564
|
-
}
|
|
565
|
-
emitBlockWithAccess(line, f) {
|
|
566
|
-
this.emitBlock([this.accessLevel, line], f);
|
|
567
|
-
}
|
|
568
|
-
justTypesCase(justTypes, notJustTypes) {
|
|
569
|
-
if (this._options.justTypes)
|
|
570
|
-
return justTypes;
|
|
571
|
-
else
|
|
572
|
-
return notJustTypes;
|
|
573
|
-
}
|
|
574
|
-
get lowerNamingFunction() {
|
|
575
|
-
return Naming_1.funPrefixNamer("lower", s => swiftNameStyle("", false, s, Acronyms_1.acronymStyle(this._options.acronymStyle)));
|
|
576
|
-
}
|
|
577
|
-
swiftPropertyType(p) {
|
|
578
|
-
if (p.isOptional || (this._options.optionalEnums && p.type.kind === "enum")) {
|
|
579
|
-
return [this.swiftType(p.type, true, true), "?"];
|
|
580
|
-
}
|
|
581
|
-
else {
|
|
582
|
-
return this.swiftType(p.type, true);
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
swiftType(t, withIssues = false, noOptional = false) {
|
|
586
|
-
const optional = noOptional ? "" : "?";
|
|
587
|
-
return TypeUtils_1.matchType(t, _anyType => {
|
|
588
|
-
this._needAny = true;
|
|
589
|
-
return Source_1.maybeAnnotated(withIssues, Annotation_1.anyTypeIssueAnnotation, this.justTypesCase(["Any", optional], "JSONAny"));
|
|
590
|
-
}, _nullType => {
|
|
591
|
-
this._needNull = true;
|
|
592
|
-
return Source_1.maybeAnnotated(withIssues, Annotation_1.nullTypeIssueAnnotation, this.justTypesCase("NSNull", ["JSONNull", optional]));
|
|
593
|
-
}, _boolType => "Bool", _integerType => "Int", _doubleType => "Double", _stringType => "String", arrayType => ["[", this.swiftType(arrayType.items, withIssues), "]"], classType => this.nameForNamedType(classType), mapType => ["[String: ", this.swiftType(mapType.values, withIssues), "]"], enumType => this.nameForNamedType(enumType), unionType => {
|
|
594
|
-
const nullable = TypeUtils_1.nullableFromUnion(unionType);
|
|
595
|
-
if (nullable !== null)
|
|
596
|
-
return [this.swiftType(nullable, withIssues), optional];
|
|
597
|
-
return this.nameForNamedType(unionType);
|
|
598
|
-
}, transformedStringType => {
|
|
599
|
-
if (transformedStringType.kind === "date-time") {
|
|
600
|
-
return "Date";
|
|
601
|
-
}
|
|
602
|
-
else {
|
|
603
|
-
return Support_2.panic(`Transformed string type ${transformedStringType.kind} not supported`);
|
|
604
|
-
}
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
proposedUnionMemberNameForTypeKind(kind) {
|
|
608
|
-
if (kind === "enum") {
|
|
609
|
-
return "enumeration";
|
|
610
|
-
}
|
|
611
|
-
if (kind === "union") {
|
|
612
|
-
return "one_of";
|
|
613
|
-
}
|
|
614
|
-
return null;
|
|
615
|
-
}
|
|
616
|
-
renderSingleFileHeaderComments() {
|
|
617
|
-
this.emitLineOnce("// This file was generated from JSON Schema using quicktype, do not modify it directly.");
|
|
618
|
-
this.emitLineOnce("// To parse the JSON, add this file to your project and do:");
|
|
619
|
-
this.emitLineOnce("//");
|
|
620
|
-
this.forEachTopLevel("none", (t, topLevelName) => {
|
|
621
|
-
if (this._options.convenienceInitializers && !(t instanceof Type_1.EnumType)) {
|
|
622
|
-
this.emitLineOnce("// let ", Source_1.modifySource(Strings_1.camelCase, topLevelName), " = try ", topLevelName, "(json)");
|
|
623
|
-
}
|
|
624
|
-
else {
|
|
625
|
-
this.emitLineOnce("// let ", Source_1.modifySource(Strings_1.camelCase, topLevelName), " = ", "try? JSONDecoder().decode(", topLevelName, ".self, from: jsonData)");
|
|
626
|
-
}
|
|
627
|
-
});
|
|
628
|
-
}
|
|
629
|
-
renderHeader(type, name) {
|
|
630
|
-
if (this.leadingComments !== undefined) {
|
|
631
|
-
this.emitCommentLines(this.leadingComments);
|
|
632
|
-
}
|
|
633
|
-
else if (!this._options.justTypes) {
|
|
634
|
-
if (this._options.multiFileOutput) {
|
|
635
|
-
this.emitLineOnce("// This file was generated from JSON Schema using quicktype, do not modify it directly.");
|
|
636
|
-
this.emitLineOnce("// To parse the JSON, add this file to your project and do:");
|
|
637
|
-
this.emitLineOnce("//");
|
|
638
|
-
if (this._options.convenienceInitializers && !(type instanceof Type_1.EnumType)) {
|
|
639
|
-
this.emitLine("// let ", Source_1.modifySource(Strings_1.camelCase, name), " = try ", name, "(json)");
|
|
640
|
-
}
|
|
641
|
-
else {
|
|
642
|
-
this.emitLine("// let ", Source_1.modifySource(Strings_1.camelCase, name), " = ", "try? newJSONDecoder().decode(", name, ".self, from: jsonData)");
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
if (this._options.alamofire) {
|
|
646
|
-
this.emitLine("//");
|
|
647
|
-
this.emitLine("// To parse values from Alamofire responses:");
|
|
648
|
-
this.emitLine("//");
|
|
649
|
-
this.emitLine("// Alamofire.request(url).response", name, " { response in");
|
|
650
|
-
this.emitLine("// if let ", Source_1.modifySource(Strings_1.camelCase, name), " = response.result.value {");
|
|
651
|
-
this.emitLine("// ...");
|
|
652
|
-
this.emitLine("// }");
|
|
653
|
-
this.emitLine("// }");
|
|
654
|
-
}
|
|
655
|
-
if (this._options.protocol.hashable || this._options.protocol.equatable) {
|
|
656
|
-
this.emitLine("//");
|
|
657
|
-
this.emitLine("// Hashable or Equatable:");
|
|
658
|
-
this.emitLine("// The compiler will not be able to synthesize the implementation of Hashable or Equatable");
|
|
659
|
-
this.emitLine("// for types that require the use of JSONAny, nor will the implementation of Hashable be");
|
|
660
|
-
this.emitLine("// synthesized for types that have collections (such as arrays or dictionaries).");
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
this.ensureBlankLine();
|
|
664
|
-
this.emitLineOnce("import Foundation");
|
|
665
|
-
if (!this._options.justTypes && this._options.alamofire) {
|
|
666
|
-
this.emitLineOnce("import Alamofire");
|
|
667
|
-
}
|
|
668
|
-
this.ensureBlankLine();
|
|
669
|
-
}
|
|
670
|
-
renderTopLevelAlias(t, name) {
|
|
671
|
-
this.emitLine(this.accessLevel, "typealias ", name, " = ", this.swiftType(t, true));
|
|
672
|
-
}
|
|
673
|
-
getProtocolsArray(_t, isClass) {
|
|
674
|
-
const protocols = [];
|
|
675
|
-
// [Michael Fey (@MrRooni), 2019-4-24] Technically NSObject isn't a "protocol" in this instance, but this felt like the best place to slot in this superclass declaration.
|
|
676
|
-
if (isClass && this._options.objcSupport) {
|
|
677
|
-
protocols.push("NSObject");
|
|
678
|
-
}
|
|
679
|
-
if (!this._options.justTypes) {
|
|
680
|
-
protocols.push("Codable");
|
|
681
|
-
}
|
|
682
|
-
if (this._options.protocol.hashable) {
|
|
683
|
-
protocols.push("Hashable");
|
|
684
|
-
}
|
|
685
|
-
if (this._options.protocol.equatable) {
|
|
686
|
-
protocols.push("Equatable");
|
|
687
|
-
}
|
|
688
|
-
return protocols;
|
|
397
|
+
return protocols;
|
|
689
398
|
}
|
|
690
399
|
getProtocolString(_t, isClass) {
|
|
691
400
|
const protocols = this.getProtocolsArray(_t, isClass);
|
|
@@ -730,7 +439,7 @@ class SwiftRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
730
439
|
if (this._options.multiFileOutput === false) {
|
|
731
440
|
return;
|
|
732
441
|
}
|
|
733
|
-
Support_1.assert(this._currentFilename === undefined, "Previous file wasn't finished: " + this._currentFilename);
|
|
442
|
+
(0, Support_1.assert)(this._currentFilename === undefined, "Previous file wasn't finished: " + this._currentFilename);
|
|
734
443
|
// FIXME: The filenames should actually be Sourcelikes, too
|
|
735
444
|
this._currentFilename = `${this.sourcelikeToString(basename)}.swift`;
|
|
736
445
|
this.initializeEmitContextForFilename(this._currentFilename);
|
|
@@ -740,7 +449,7 @@ class SwiftRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
740
449
|
if (this._options.multiFileOutput === false) {
|
|
741
450
|
return;
|
|
742
451
|
}
|
|
743
|
-
this.finishFile(Support_1.defined(this._currentFilename));
|
|
452
|
+
this.finishFile((0, Support_1.defined)(this._currentFilename));
|
|
744
453
|
this._currentFilename = undefined;
|
|
745
454
|
}
|
|
746
455
|
propertyLinesDefinition(name, parameter) {
|
|
@@ -834,7 +543,7 @@ class SwiftRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
834
543
|
this.emitLine("case ", name, ' = "', label, '"');
|
|
835
544
|
}
|
|
836
545
|
else {
|
|
837
|
-
const names = collection_utils_1.arrayIntercalate(", ", group.map(p => p.name));
|
|
546
|
+
const names = (0, collection_utils_1.arrayIntercalate)(", ", group.map(p => p.name));
|
|
838
547
|
this.emitLine("case ", names);
|
|
839
548
|
}
|
|
840
549
|
}
|
|
@@ -999,135 +708,429 @@ encoder.dateEncodingStrategy = .formatted(formatter)`);
|
|
|
999
708
|
protocols.push("String"); // Not a protocol
|
|
1000
709
|
protocols.push("Codable");
|
|
1001
710
|
}
|
|
1002
|
-
if (this._options.protocol.hashable) {
|
|
1003
|
-
protocols.push("Hashable");
|
|
711
|
+
if (this._options.protocol.hashable) {
|
|
712
|
+
protocols.push("Hashable");
|
|
713
|
+
}
|
|
714
|
+
if (this._options.protocol.equatable) {
|
|
715
|
+
protocols.push("Equatable");
|
|
716
|
+
}
|
|
717
|
+
const protocolString = protocols.length > 0 ? ": " + protocols.join(", ") : "";
|
|
718
|
+
if (this._options.justTypes) {
|
|
719
|
+
this.emitBlockWithAccess(["enum ", enumName, protocolString], () => {
|
|
720
|
+
this.forEachEnumCase(e, "none", name => {
|
|
721
|
+
this.emitLine("case ", name);
|
|
722
|
+
});
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
else {
|
|
726
|
+
this.emitBlockWithAccess(["enum ", enumName, protocolString], () => {
|
|
727
|
+
this.forEachEnumCase(e, "none", (name, jsonName) => {
|
|
728
|
+
this.emitLine("case ", name, ' = "', stringEscape(jsonName), '"');
|
|
729
|
+
});
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
this.endFile();
|
|
733
|
+
}
|
|
734
|
+
renderUnionDefinition(u, unionName) {
|
|
735
|
+
this.startFile(unionName);
|
|
736
|
+
this.emitLineOnce("import Foundation");
|
|
737
|
+
this.ensureBlankLine();
|
|
738
|
+
function sortBy(t) {
|
|
739
|
+
const kind = t.kind;
|
|
740
|
+
if (kind === "class")
|
|
741
|
+
return kind;
|
|
742
|
+
return "_" + kind;
|
|
743
|
+
}
|
|
744
|
+
const renderUnionCase = (t) => {
|
|
745
|
+
this.emitBlock(["if let x = try? container.decode(", this.swiftType(t), ".self)"], () => {
|
|
746
|
+
this.emitLine("self = .", this.nameForUnionMember(u, t), "(x)");
|
|
747
|
+
this.emitLine("return");
|
|
748
|
+
});
|
|
749
|
+
};
|
|
750
|
+
this.emitDescription(this.descriptionForType(u));
|
|
751
|
+
const indirect = this.isCycleBreakerType(u) ? "indirect " : "";
|
|
752
|
+
const [maybeNull, nonNulls] = (0, TypeUtils_1.removeNullFromUnion)(u, sortBy);
|
|
753
|
+
this.emitBlockWithAccess([indirect, "enum ", unionName, this.getProtocolString(u, false)], () => {
|
|
754
|
+
this.forEachUnionMember(u, nonNulls, "none", null, (name, t) => {
|
|
755
|
+
this.emitLine("case ", name, "(", this.swiftType(t), ")");
|
|
756
|
+
});
|
|
757
|
+
if (maybeNull !== null) {
|
|
758
|
+
this.emitLine("case ", this.nameForUnionMember(u, maybeNull));
|
|
759
|
+
}
|
|
760
|
+
if (!this._options.justTypes) {
|
|
761
|
+
this.ensureBlankLine();
|
|
762
|
+
this.emitBlockWithAccess("init(from decoder: Decoder) throws", () => {
|
|
763
|
+
this.emitLine("let container = try decoder.singleValueContainer()");
|
|
764
|
+
const boolMember = u.findMember("bool");
|
|
765
|
+
if (boolMember !== undefined)
|
|
766
|
+
renderUnionCase(boolMember);
|
|
767
|
+
const integerMember = u.findMember("integer");
|
|
768
|
+
if (integerMember !== undefined)
|
|
769
|
+
renderUnionCase(integerMember);
|
|
770
|
+
for (const t of nonNulls) {
|
|
771
|
+
if (t.kind === "bool" || t.kind === "integer")
|
|
772
|
+
continue;
|
|
773
|
+
renderUnionCase(t);
|
|
774
|
+
}
|
|
775
|
+
if (maybeNull !== null) {
|
|
776
|
+
this.emitBlock("if container.decodeNil()", () => {
|
|
777
|
+
this.emitLine("self = .", this.nameForUnionMember(u, maybeNull));
|
|
778
|
+
this.emitLine("return");
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
this.emitDecodingError(unionName);
|
|
782
|
+
});
|
|
783
|
+
this.ensureBlankLine();
|
|
784
|
+
this.emitBlockWithAccess("func encode(to encoder: Encoder) throws", () => {
|
|
785
|
+
this.emitLine("var container = encoder.singleValueContainer()");
|
|
786
|
+
this.emitLine("switch self {");
|
|
787
|
+
this.forEachUnionMember(u, nonNulls, "none", null, (name, _) => {
|
|
788
|
+
this.emitLine("case .", name, "(let x):");
|
|
789
|
+
this.indent(() => this.emitLine("try container.encode(x)"));
|
|
790
|
+
});
|
|
791
|
+
if (maybeNull !== null) {
|
|
792
|
+
this.emitLine("case .", this.nameForUnionMember(u, maybeNull), ":");
|
|
793
|
+
this.indent(() => this.emitLine("try container.encodeNil()"));
|
|
794
|
+
}
|
|
795
|
+
this.emitLine("}");
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
});
|
|
799
|
+
this.endFile();
|
|
800
|
+
}
|
|
801
|
+
emitTopLevelMapAndArrayConvenienceInitializerExtensions(t, name) {
|
|
802
|
+
let extensionSource;
|
|
803
|
+
if (t instanceof Type_1.ArrayType) {
|
|
804
|
+
extensionSource = ["Array where Element == ", name, ".Element"];
|
|
805
|
+
}
|
|
806
|
+
else if (t instanceof Type_1.MapType) {
|
|
807
|
+
extensionSource = ["Dictionary where Key == String, Value == ", this.swiftType(t.values)];
|
|
808
|
+
}
|
|
809
|
+
else {
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
this.emitBlockWithAccess(["extension ", extensionSource], () => {
|
|
813
|
+
this.emitBlock(["init(data: Data) throws"], () => {
|
|
814
|
+
this.emitLine("self = try newJSONDecoder().decode(", name, ".self, from: data)");
|
|
815
|
+
});
|
|
816
|
+
this.ensureBlankLine();
|
|
817
|
+
this.emitBlock("init(_ json: String, using encoding: String.Encoding = .utf8) throws", () => {
|
|
818
|
+
this.emitBlock("guard let data = json.data(using: encoding) else", () => {
|
|
819
|
+
this.emitLine(`throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)`);
|
|
820
|
+
});
|
|
821
|
+
this.emitLine("try self.init(data: data)");
|
|
822
|
+
});
|
|
823
|
+
this.ensureBlankLine();
|
|
824
|
+
this.emitBlock(`init(fromURL url: URL) throws`, () => {
|
|
825
|
+
this.emitLine("try self.init(data: try Data(contentsOf: url))");
|
|
826
|
+
});
|
|
827
|
+
this.ensureBlankLine();
|
|
828
|
+
this.emitBlock("func jsonData() throws -> Data", () => {
|
|
829
|
+
this.emitLine("return try newJSONEncoder().encode(self)");
|
|
830
|
+
});
|
|
831
|
+
this.ensureBlankLine();
|
|
832
|
+
this.emitBlock("func jsonString(encoding: String.Encoding = .utf8) throws -> String?", () => {
|
|
833
|
+
this.emitLine("return String(data: try self.jsonData(), encoding: encoding)");
|
|
834
|
+
});
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
emitDecodingError(name) {
|
|
838
|
+
this.emitLine("throw DecodingError.typeMismatch(", name, '.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ', name, '"))');
|
|
839
|
+
}
|
|
840
|
+
emitSupportFunctions4 = () => {
|
|
841
|
+
this.startFile("JSONSchemaSupport");
|
|
842
|
+
this.emitLineOnce("import Foundation");
|
|
843
|
+
this.forEachTopLevel("leading", (t, name) => this.renderTopLevelAlias(t, name), t => this.namedTypeToNameForTopLevel(t) === undefined);
|
|
844
|
+
if (this._options.convenienceInitializers) {
|
|
845
|
+
this.ensureBlankLine();
|
|
846
|
+
this.forEachTopLevel("leading-and-interposing", (t, name) => this.emitTopLevelMapAndArrayConvenienceInitializerExtensions(t, name));
|
|
847
|
+
}
|
|
848
|
+
if ((!this._options.justTypes && this._options.convenienceInitializers) || this._options.alamofire) {
|
|
849
|
+
this.ensureBlankLine();
|
|
850
|
+
this.emitMark("Helper functions for creating encoders and decoders", true);
|
|
851
|
+
this.ensureBlankLine();
|
|
852
|
+
this.emitNewEncoderDecoder();
|
|
853
|
+
}
|
|
854
|
+
if (this._options.alamofire) {
|
|
855
|
+
this.ensureBlankLine();
|
|
856
|
+
this.emitMark("Alamofire response handlers", true);
|
|
857
|
+
this.ensureBlankLine();
|
|
858
|
+
this.emitAlamofireExtension();
|
|
859
|
+
}
|
|
860
|
+
// This assumes that this method is called after declarations
|
|
861
|
+
// are emitted.
|
|
862
|
+
if (this._needAny || this._needNull) {
|
|
863
|
+
this.ensureBlankLine();
|
|
864
|
+
this.emitMark("Encode/decode helpers", true);
|
|
865
|
+
this.ensureBlankLine();
|
|
866
|
+
if (this._options.objcSupport) {
|
|
867
|
+
this.emitLine(this.objcMembersDeclaration, this.accessLevel, "class JSONNull: NSObject, Codable {");
|
|
868
|
+
}
|
|
869
|
+
else {
|
|
870
|
+
this.emitLine(this.accessLevel, "class JSONNull: Codable, Hashable {");
|
|
871
|
+
}
|
|
872
|
+
this.ensureBlankLine();
|
|
873
|
+
this.emitMultiline(` public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
|
|
874
|
+
return true
|
|
875
|
+
}`);
|
|
876
|
+
if (this._options.objcSupport === false) {
|
|
877
|
+
this.ensureBlankLine();
|
|
878
|
+
this.emitMultiline(` public var hashValue: Int {
|
|
879
|
+
return 0
|
|
880
|
+
}`);
|
|
881
|
+
if (this._options.swift5Support) {
|
|
882
|
+
this.ensureBlankLine();
|
|
883
|
+
this.emitMultiline(` public func hash(into hasher: inout Hasher) {
|
|
884
|
+
// No-op
|
|
885
|
+
}`);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
this.ensureBlankLine();
|
|
889
|
+
if (this._options.objcSupport) {
|
|
890
|
+
this.emitItem(" override ");
|
|
891
|
+
}
|
|
892
|
+
else {
|
|
893
|
+
this.emitItem(" ");
|
|
894
|
+
}
|
|
895
|
+
this.emitMultiline(`public init() {}
|
|
896
|
+
|
|
897
|
+
public required init(from decoder: Decoder) throws {
|
|
898
|
+
let container = try decoder.singleValueContainer()
|
|
899
|
+
if !container.decodeNil() {
|
|
900
|
+
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
public func encode(to encoder: Encoder) throws {
|
|
905
|
+
var container = encoder.singleValueContainer()
|
|
906
|
+
try container.encodeNil()
|
|
907
|
+
}
|
|
908
|
+
}`);
|
|
909
|
+
}
|
|
910
|
+
if (this._needAny) {
|
|
911
|
+
this.ensureBlankLine();
|
|
912
|
+
this.emitMultiline(`class JSONCodingKey: CodingKey {
|
|
913
|
+
let key: String
|
|
914
|
+
|
|
915
|
+
required init?(intValue: Int) {
|
|
916
|
+
return nil
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
required init?(stringValue: String) {
|
|
920
|
+
key = stringValue
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
var intValue: Int? {
|
|
924
|
+
return nil
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
var stringValue: String {
|
|
928
|
+
return key
|
|
929
|
+
}
|
|
930
|
+
}`);
|
|
931
|
+
this.ensureBlankLine();
|
|
932
|
+
if (this._options.objcSupport) {
|
|
933
|
+
this.emitLine(this.objcMembersDeclaration, this.accessLevel, "class JSONAny: NSObject, Codable {");
|
|
934
|
+
}
|
|
935
|
+
else {
|
|
936
|
+
this.emitLine(this.accessLevel, "class JSONAny: Codable {");
|
|
937
|
+
}
|
|
938
|
+
this.ensureBlankLine();
|
|
939
|
+
this.emitMultiline(` ${this.accessLevel}let value: Any
|
|
940
|
+
|
|
941
|
+
static func decodingError(forCodingPath codingPath: [CodingKey]) -> DecodingError {
|
|
942
|
+
let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Cannot decode JSONAny")
|
|
943
|
+
return DecodingError.typeMismatch(JSONAny.self, context)
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
static func encodingError(forValue value: Any, codingPath: [CodingKey]) -> EncodingError {
|
|
947
|
+
let context = EncodingError.Context(codingPath: codingPath, debugDescription: "Cannot encode JSONAny")
|
|
948
|
+
return EncodingError.invalidValue(value, context)
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
static func decode(from container: SingleValueDecodingContainer) throws -> Any {
|
|
952
|
+
if let value = try? container.decode(Bool.self) {
|
|
953
|
+
return value
|
|
954
|
+
}
|
|
955
|
+
if let value = try? container.decode(Int64.self) {
|
|
956
|
+
return value
|
|
957
|
+
}
|
|
958
|
+
if let value = try? container.decode(Double.self) {
|
|
959
|
+
return value
|
|
960
|
+
}
|
|
961
|
+
if let value = try? container.decode(String.self) {
|
|
962
|
+
return value
|
|
963
|
+
}
|
|
964
|
+
if container.decodeNil() {
|
|
965
|
+
return JSONNull()
|
|
966
|
+
}
|
|
967
|
+
throw decodingError(forCodingPath: container.codingPath)
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
static func decode(from container: inout UnkeyedDecodingContainer) throws -> Any {
|
|
971
|
+
if let value = try? container.decode(Bool.self) {
|
|
972
|
+
return value
|
|
973
|
+
}
|
|
974
|
+
if let value = try? container.decode(Int64.self) {
|
|
975
|
+
return value
|
|
976
|
+
}
|
|
977
|
+
if let value = try? container.decode(Double.self) {
|
|
978
|
+
return value
|
|
1004
979
|
}
|
|
1005
|
-
if (
|
|
1006
|
-
|
|
980
|
+
if let value = try? container.decode(String.self) {
|
|
981
|
+
return value
|
|
1007
982
|
}
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
this.emitLine("case ", name);
|
|
1013
|
-
});
|
|
1014
|
-
});
|
|
983
|
+
if let value = try? container.decodeNil() {
|
|
984
|
+
if value {
|
|
985
|
+
return JSONNull()
|
|
986
|
+
}
|
|
1015
987
|
}
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
this.forEachEnumCase(e, "none", (name, jsonName) => {
|
|
1019
|
-
this.emitLine("case ", name, ' = "', stringEscape(jsonName), '"');
|
|
1020
|
-
});
|
|
1021
|
-
});
|
|
988
|
+
if var container = try? container.nestedUnkeyedContainer() {
|
|
989
|
+
return try decodeArray(from: &container)
|
|
1022
990
|
}
|
|
1023
|
-
|
|
991
|
+
if var container = try? container.nestedContainer(keyedBy: JSONCodingKey.self) {
|
|
992
|
+
return try decodeDictionary(from: &container)
|
|
993
|
+
}
|
|
994
|
+
throw decodingError(forCodingPath: container.codingPath)
|
|
1024
995
|
}
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
function sortBy(t) {
|
|
1030
|
-
const kind = t.kind;
|
|
1031
|
-
if (kind === "class")
|
|
1032
|
-
return kind;
|
|
1033
|
-
return "_" + kind;
|
|
996
|
+
|
|
997
|
+
static func decode(from container: inout KeyedDecodingContainer<JSONCodingKey>, forKey key: JSONCodingKey) throws -> Any {
|
|
998
|
+
if let value = try? container.decode(Bool.self, forKey: key) {
|
|
999
|
+
return value
|
|
1034
1000
|
}
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
});
|
|
1048
|
-
if (maybeNull !== null) {
|
|
1049
|
-
this.emitLine("case ", this.nameForUnionMember(u, maybeNull));
|
|
1001
|
+
if let value = try? container.decode(Int64.self, forKey: key) {
|
|
1002
|
+
return value
|
|
1003
|
+
}
|
|
1004
|
+
if let value = try? container.decode(Double.self, forKey: key) {
|
|
1005
|
+
return value
|
|
1006
|
+
}
|
|
1007
|
+
if let value = try? container.decode(String.self, forKey: key) {
|
|
1008
|
+
return value
|
|
1009
|
+
}
|
|
1010
|
+
if let value = try? container.decodeNil(forKey: key) {
|
|
1011
|
+
if value {
|
|
1012
|
+
return JSONNull()
|
|
1050
1013
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1014
|
+
}
|
|
1015
|
+
if var container = try? container.nestedUnkeyedContainer(forKey: key) {
|
|
1016
|
+
return try decodeArray(from: &container)
|
|
1017
|
+
}
|
|
1018
|
+
if var container = try? container.nestedContainer(keyedBy: JSONCodingKey.self, forKey: key) {
|
|
1019
|
+
return try decodeDictionary(from: &container)
|
|
1020
|
+
}
|
|
1021
|
+
throw decodingError(forCodingPath: container.codingPath)
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
static func decodeArray(from container: inout UnkeyedDecodingContainer) throws -> [Any] {
|
|
1025
|
+
var arr: [Any] = []
|
|
1026
|
+
while !container.isAtEnd {
|
|
1027
|
+
let value = try decode(from: &container)
|
|
1028
|
+
arr.append(value)
|
|
1029
|
+
}
|
|
1030
|
+
return arr
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
static func decodeDictionary(from container: inout KeyedDecodingContainer<JSONCodingKey>) throws -> [String: Any] {
|
|
1034
|
+
var dict = [String: Any]()
|
|
1035
|
+
for key in container.allKeys {
|
|
1036
|
+
let value = try decode(from: &container, forKey: key)
|
|
1037
|
+
dict[key.stringValue] = value
|
|
1038
|
+
}
|
|
1039
|
+
return dict
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
static func encode(to container: inout UnkeyedEncodingContainer, array: [Any]) throws {
|
|
1043
|
+
for value in array {
|
|
1044
|
+
if let value = value as? Bool {
|
|
1045
|
+
try container.encode(value)
|
|
1046
|
+
} else if let value = value as? Int64 {
|
|
1047
|
+
try container.encode(value)
|
|
1048
|
+
} else if let value = value as? Double {
|
|
1049
|
+
try container.encode(value)
|
|
1050
|
+
} else if let value = value as? String {
|
|
1051
|
+
try container.encode(value)
|
|
1052
|
+
} else if value is JSONNull {
|
|
1053
|
+
try container.encodeNil()
|
|
1054
|
+
} else if let value = value as? [Any] {
|
|
1055
|
+
var container = container.nestedUnkeyedContainer()
|
|
1056
|
+
try encode(to: &container, array: value)
|
|
1057
|
+
} else if let value = value as? [String: Any] {
|
|
1058
|
+
var container = container.nestedContainer(keyedBy: JSONCodingKey.self)
|
|
1059
|
+
try encode(to: &container, dictionary: value)
|
|
1060
|
+
} else {
|
|
1061
|
+
throw encodingError(forValue: value, codingPath: container.codingPath)
|
|
1088
1062
|
}
|
|
1089
|
-
}
|
|
1090
|
-
this.endFile();
|
|
1063
|
+
}
|
|
1091
1064
|
}
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1065
|
+
|
|
1066
|
+
static func encode(to container: inout KeyedEncodingContainer<JSONCodingKey>, dictionary: [String: Any]) throws {
|
|
1067
|
+
for (key, value) in dictionary {
|
|
1068
|
+
let key = JSONCodingKey(stringValue: key)!
|
|
1069
|
+
if let value = value as? Bool {
|
|
1070
|
+
try container.encode(value, forKey: key)
|
|
1071
|
+
} else if let value = value as? Int64 {
|
|
1072
|
+
try container.encode(value, forKey: key)
|
|
1073
|
+
} else if let value = value as? Double {
|
|
1074
|
+
try container.encode(value, forKey: key)
|
|
1075
|
+
} else if let value = value as? String {
|
|
1076
|
+
try container.encode(value, forKey: key)
|
|
1077
|
+
} else if value is JSONNull {
|
|
1078
|
+
try container.encodeNil(forKey: key)
|
|
1079
|
+
} else if let value = value as? [Any] {
|
|
1080
|
+
var container = container.nestedUnkeyedContainer(forKey: key)
|
|
1081
|
+
try encode(to: &container, array: value)
|
|
1082
|
+
} else if let value = value as? [String: Any] {
|
|
1083
|
+
var container = container.nestedContainer(keyedBy: JSONCodingKey.self, forKey: key)
|
|
1084
|
+
try encode(to: &container, dictionary: value)
|
|
1085
|
+
} else {
|
|
1086
|
+
throw encodingError(forValue: value, codingPath: container.codingPath)
|
|
1087
|
+
}
|
|
1096
1088
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
static func encode(to container: inout SingleValueEncodingContainer, value: Any) throws {
|
|
1092
|
+
if let value = value as? Bool {
|
|
1093
|
+
try container.encode(value)
|
|
1094
|
+
} else if let value = value as? Int64 {
|
|
1095
|
+
try container.encode(value)
|
|
1096
|
+
} else if let value = value as? Double {
|
|
1097
|
+
try container.encode(value)
|
|
1098
|
+
} else if let value = value as? String {
|
|
1099
|
+
try container.encode(value)
|
|
1100
|
+
} else if value is JSONNull {
|
|
1101
|
+
try container.encodeNil()
|
|
1102
|
+
} else {
|
|
1103
|
+
throw encodingError(forValue: value, codingPath: container.codingPath)
|
|
1099
1104
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
public required init(from decoder: Decoder) throws {
|
|
1108
|
+
if var arrayContainer = try? decoder.unkeyedContainer() {
|
|
1109
|
+
self.value = try JSONAny.decodeArray(from: &arrayContainer)
|
|
1110
|
+
} else if var container = try? decoder.container(keyedBy: JSONCodingKey.self) {
|
|
1111
|
+
self.value = try JSONAny.decodeDictionary(from: &container)
|
|
1112
|
+
} else {
|
|
1113
|
+
let container = try decoder.singleValueContainer()
|
|
1114
|
+
self.value = try JSONAny.decode(from: container)
|
|
1102
1115
|
}
|
|
1103
|
-
this.emitBlockWithAccess(["extension ", extensionSource], () => {
|
|
1104
|
-
this.emitBlock(["init(data: Data) throws"], () => {
|
|
1105
|
-
this.emitLine("self = try newJSONDecoder().decode(", name, ".self, from: data)");
|
|
1106
|
-
});
|
|
1107
|
-
this.ensureBlankLine();
|
|
1108
|
-
this.emitBlock("init(_ json: String, using encoding: String.Encoding = .utf8) throws", () => {
|
|
1109
|
-
this.emitBlock("guard let data = json.data(using: encoding) else", () => {
|
|
1110
|
-
this.emitLine(`throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)`);
|
|
1111
|
-
});
|
|
1112
|
-
this.emitLine("try self.init(data: data)");
|
|
1113
|
-
});
|
|
1114
|
-
this.ensureBlankLine();
|
|
1115
|
-
this.emitBlock(`init(fromURL url: URL) throws`, () => {
|
|
1116
|
-
this.emitLine("try self.init(data: try Data(contentsOf: url))");
|
|
1117
|
-
});
|
|
1118
|
-
this.ensureBlankLine();
|
|
1119
|
-
this.emitBlock("func jsonData() throws -> Data", () => {
|
|
1120
|
-
this.emitLine("return try newJSONEncoder().encode(self)");
|
|
1121
|
-
});
|
|
1122
|
-
this.ensureBlankLine();
|
|
1123
|
-
this.emitBlock("func jsonString(encoding: String.Encoding = .utf8) throws -> String?", () => {
|
|
1124
|
-
this.emitLine("return String(data: try self.jsonData(), encoding: encoding)");
|
|
1125
|
-
});
|
|
1126
|
-
});
|
|
1127
1116
|
}
|
|
1128
|
-
|
|
1129
|
-
|
|
1117
|
+
|
|
1118
|
+
public func encode(to encoder: Encoder) throws {
|
|
1119
|
+
if let arr = self.value as? [Any] {
|
|
1120
|
+
var container = encoder.unkeyedContainer()
|
|
1121
|
+
try JSONAny.encode(to: &container, array: arr)
|
|
1122
|
+
} else if let dict = self.value as? [String: Any] {
|
|
1123
|
+
var container = encoder.container(keyedBy: JSONCodingKey.self)
|
|
1124
|
+
try JSONAny.encode(to: &container, dictionary: dict)
|
|
1125
|
+
} else {
|
|
1126
|
+
var container = encoder.singleValueContainer()
|
|
1127
|
+
try JSONAny.encode(to: &container, value: self.value)
|
|
1128
|
+
}
|
|
1130
1129
|
}
|
|
1130
|
+
}`);
|
|
1131
|
+
}
|
|
1132
|
+
this.endFile();
|
|
1133
|
+
};
|
|
1131
1134
|
emitConvenienceMutator(c, className) {
|
|
1132
1135
|
this.emitLine("func with(");
|
|
1133
1136
|
this.indent(() => {
|