quicktype 18.0.5 → 19.0.4
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/README.md +1 -1
- package/dist/{cli/CompressedJSONFromStream.d.ts → CompressedJSONFromStream.d.ts} +1 -1
- package/dist/{cli/CompressedJSONFromStream.js → CompressedJSONFromStream.js} +2 -2
- package/dist/{cli/GraphQLIntrospection.d.ts → GraphQLIntrospection.d.ts} +0 -0
- package/dist/{cli/GraphQLIntrospection.js → GraphQLIntrospection.js} +1 -1
- package/dist/{cli/TypeSource.d.ts → TypeSource.d.ts} +2 -2
- package/dist/{cli/TypeSource.js → TypeSource.js} +0 -0
- package/dist/{cli/URLGrammar.d.ts → URLGrammar.d.ts} +0 -0
- package/dist/{cli/URLGrammar.js → URLGrammar.js} +1 -1
- package/dist/{cli/index.d.ts → index.d.ts} +1 -1
- package/dist/{cli/index.js → index.js} +4 -5
- package/package.json +61 -77
- package/dist/quicktype-core/Annotation.d.ts +0 -8
- package/dist/quicktype-core/Annotation.js +0 -16
- package/dist/quicktype-core/ConvenienceRenderer.d.ts +0 -138
- package/dist/quicktype-core/ConvenienceRenderer.js +0 -668
- package/dist/quicktype-core/DateTime.d.ts +0 -10
- package/dist/quicktype-core/DateTime.js +0 -57
- package/dist/quicktype-core/DeclarationIR.d.ts +0 -14
- package/dist/quicktype-core/DeclarationIR.js +0 -167
- package/dist/quicktype-core/EncodedMarkovChain.d.ts +0 -1
- package/dist/quicktype-core/EncodedMarkovChain.js +0 -4
- package/dist/quicktype-core/GatherNames.d.ts +0 -2
- package/dist/quicktype-core/GatherNames.js +0 -333
- package/dist/quicktype-core/Graph.d.ts +0 -12
- package/dist/quicktype-core/Graph.js +0 -220
- package/dist/quicktype-core/GraphRewriting.d.ts +0 -87
- package/dist/quicktype-core/GraphRewriting.js +0 -421
- package/dist/quicktype-core/MakeTransformations.d.ts +0 -4
- package/dist/quicktype-core/MakeTransformations.js +0 -193
- package/dist/quicktype-core/MarkovChain.d.ts +0 -15
- package/dist/quicktype-core/MarkovChain.js +0 -154
- package/dist/quicktype-core/Messages.d.ts +0 -294
- package/dist/quicktype-core/Messages.js +0 -105
- package/dist/quicktype-core/Naming.d.ts +0 -64
- package/dist/quicktype-core/Naming.js +0 -356
- package/dist/quicktype-core/Renderer.d.ts +0 -50
- package/dist/quicktype-core/Renderer.js +0 -274
- package/dist/quicktype-core/RendererOptions.d.ts +0 -71
- package/dist/quicktype-core/RendererOptions.js +0 -141
- package/dist/quicktype-core/Run.d.ts +0 -174
- package/dist/quicktype-core/Run.js +0 -393
- package/dist/quicktype-core/Source.d.ts +0 -65
- package/dist/quicktype-core/Source.js +0 -204
- package/dist/quicktype-core/TargetLanguage.d.ts +0 -34
- package/dist/quicktype-core/TargetLanguage.js +0 -66
- package/dist/quicktype-core/Transformers.d.ts +0 -209
- package/dist/quicktype-core/Transformers.js +0 -836
- package/dist/quicktype-core/Type.d.ts +0 -206
- package/dist/quicktype-core/Type.js +0 -716
- package/dist/quicktype-core/TypeBuilder.d.ts +0 -61
- package/dist/quicktype-core/TypeBuilder.js +0 -324
- package/dist/quicktype-core/TypeGraph.d.ts +0 -75
- package/dist/quicktype-core/TypeGraph.js +0 -420
- package/dist/quicktype-core/TypeUtils.d.ts +0 -33
- package/dist/quicktype-core/TypeUtils.js +0 -230
- package/dist/quicktype-core/UnifyClasses.d.ts +0 -16
- package/dist/quicktype-core/UnifyClasses.js +0 -159
- package/dist/quicktype-core/UnionBuilder.d.ts +0 -49
- package/dist/quicktype-core/UnionBuilder.js +0 -282
- package/dist/quicktype-core/attributes/AccessorNames.d.ts +0 -18
- package/dist/quicktype-core/attributes/AccessorNames.js +0 -182
- package/dist/quicktype-core/attributes/Constraints.d.ts +0 -38
- package/dist/quicktype-core/attributes/Constraints.js +0 -172
- package/dist/quicktype-core/attributes/Description.d.ts +0 -9
- package/dist/quicktype-core/attributes/Description.js +0 -97
- package/dist/quicktype-core/attributes/EnumValues.d.ts +0 -8
- package/dist/quicktype-core/attributes/EnumValues.js +0 -31
- package/dist/quicktype-core/attributes/StringTypes.d.ts +0 -28
- package/dist/quicktype-core/attributes/StringTypes.js +0 -189
- package/dist/quicktype-core/attributes/TypeAttributes.d.ts +0 -34
- package/dist/quicktype-core/attributes/TypeAttributes.js +0 -119
- package/dist/quicktype-core/attributes/TypeNames.d.ts +0 -46
- package/dist/quicktype-core/attributes/TypeNames.js +0 -274
- package/dist/quicktype-core/attributes/URIAttributes.d.ts +0 -8
- package/dist/quicktype-core/attributes/URIAttributes.js +0 -85
- package/dist/quicktype-core/index.d.ts +0 -48
- package/dist/quicktype-core/index.js +0 -180
- package/dist/quicktype-core/input/CompressedJSON.d.ts +0 -69
- package/dist/quicktype-core/input/CompressedJSON.js +0 -276
- package/dist/quicktype-core/input/FetchingJSONSchemaStore.d.ts +0 -6
- package/dist/quicktype-core/input/FetchingJSONSchemaStore.js +0 -18
- package/dist/quicktype-core/input/Inference.d.ts +0 -22
- package/dist/quicktype-core/input/Inference.js +0 -240
- package/dist/quicktype-core/input/Inputs.d.ts +0 -48
- package/dist/quicktype-core/input/Inputs.js +0 -145
- package/dist/quicktype-core/input/JSONSchemaInput.d.ts +0 -91
- package/dist/quicktype-core/input/JSONSchemaInput.js +0 -1041
- package/dist/quicktype-core/input/JSONSchemaStore.d.ts +0 -8
- package/dist/quicktype-core/input/JSONSchemaStore.js +0 -36
- package/dist/quicktype-core/input/PostmanCollection.d.ts +0 -5
- package/dist/quicktype-core/input/PostmanCollection.js +0 -60
- package/dist/quicktype-core/input/io/NodeIO.d.ts +0 -3
- package/dist/quicktype-core/input/io/NodeIO.js +0 -87
- package/dist/quicktype-core/input/io/get-stream/buffer-stream.d.ts +0 -2
- package/dist/quicktype-core/input/io/get-stream/buffer-stream.js +0 -45
- package/dist/quicktype-core/input/io/get-stream/index.d.ts +0 -9
- package/dist/quicktype-core/input/io/get-stream/index.js +0 -52
- package/dist/quicktype-core/language/All.d.ts +0 -3
- package/dist/quicktype-core/language/All.js +0 -57
- package/dist/quicktype-core/language/CPlusPlus.d.ts +0 -241
- package/dist/quicktype-core/language/CPlusPlus.js +0 -1847
- package/dist/quicktype-core/language/CSharp.d.ts +0 -201
- package/dist/quicktype-core/language/CSharp.js +0 -1850
- package/dist/quicktype-core/language/Crystal.d.ts +0 -37
- package/dist/quicktype-core/language/Crystal.js +0 -337
- package/dist/quicktype-core/language/Dart.d.ts +0 -66
- package/dist/quicktype-core/language/Dart.js +0 -576
- package/dist/quicktype-core/language/Elm.d.ts +0 -58
- package/dist/quicktype-core/language/Elm.js +0 -522
- package/dist/quicktype-core/language/Golang.d.ts +0 -51
- package/dist/quicktype-core/language/Golang.js +0 -460
- package/dist/quicktype-core/language/Haskell.d.ts +0 -56
- package/dist/quicktype-core/language/Haskell.js +0 -411
- package/dist/quicktype-core/language/JSONSchema.d.ts +0 -31
- package/dist/quicktype-core/language/JSONSchema.js +0 -169
- package/dist/quicktype-core/language/Java.d.ts +0 -125
- package/dist/quicktype-core/language/Java.js +0 -1081
- package/dist/quicktype-core/language/JavaScript.d.ts +0 -68
- package/dist/quicktype-core/language/JavaScript.js +0 -435
- package/dist/quicktype-core/language/JavaScriptPropTypes.d.ts +0 -40
- package/dist/quicktype-core/language/JavaScriptPropTypes.js +0 -213
- package/dist/quicktype-core/language/JavaScriptUnicodeMaps.d.ts +0 -2
- package/dist/quicktype-core/language/JavaScriptUnicodeMaps.js +0 -134
- package/dist/quicktype-core/language/Kotlin.d.ts +0 -109
- package/dist/quicktype-core/language/Kotlin.js +0 -832
- package/dist/quicktype-core/language/Objective-C.d.ts +0 -79
- package/dist/quicktype-core/language/Objective-C.js +0 -777
- package/dist/quicktype-core/language/Php.d.ts +0 -80
- package/dist/quicktype-core/language/Php.js +0 -702
- package/dist/quicktype-core/language/Pike.d.ts +0 -37
- package/dist/quicktype-core/language/Pike.js +0 -276
- package/dist/quicktype-core/language/Python.d.ts +0 -107
- package/dist/quicktype-core/language/Python.js +0 -969
- package/dist/quicktype-core/language/Rust.d.ts +0 -56
- package/dist/quicktype-core/language/Rust.js +0 -309
- package/dist/quicktype-core/language/Swift.d.ts +0 -96
- package/dist/quicktype-core/language/Swift.js +0 -1211
- package/dist/quicktype-core/language/TypeScriptFlow.d.ts +0 -77
- package/dist/quicktype-core/language/TypeScriptFlow.js +0 -286
- package/dist/quicktype-core/language/ruby/index.d.ts +0 -52
- package/dist/quicktype-core/language/ruby/index.js +0 -557
- package/dist/quicktype-core/language/ruby/keywords.d.ts +0 -3
- package/dist/quicktype-core/language/ruby/keywords.js +0 -358
- package/dist/quicktype-core/rewrites/CombineClasses.d.ts +0 -3
- package/dist/quicktype-core/rewrites/CombineClasses.js +0 -125
- package/dist/quicktype-core/rewrites/ExpandStrings.d.ts +0 -4
- package/dist/quicktype-core/rewrites/ExpandStrings.js +0 -143
- package/dist/quicktype-core/rewrites/FlattenStrings.d.ts +0 -3
- package/dist/quicktype-core/rewrites/FlattenStrings.js +0 -45
- package/dist/quicktype-core/rewrites/FlattenUnions.d.ts +0 -3
- package/dist/quicktype-core/rewrites/FlattenUnions.js +0 -47
- package/dist/quicktype-core/rewrites/InferMaps.d.ts +0 -3
- package/dist/quicktype-core/rewrites/InferMaps.js +0 -117
- package/dist/quicktype-core/rewrites/ReplaceObjectType.d.ts +0 -3
- package/dist/quicktype-core/rewrites/ReplaceObjectType.js +0 -60
- package/dist/quicktype-core/rewrites/ResolveIntersections.d.ts +0 -3
- package/dist/quicktype-core/rewrites/ResolveIntersections.js +0 -244
- package/dist/quicktype-core/support/Acronyms.d.ts +0 -10
- package/dist/quicktype-core/support/Acronyms.js +0 -1128
- package/dist/quicktype-core/support/Chance.d.ts +0 -38
- package/dist/quicktype-core/support/Chance.js +0 -2146
- package/dist/quicktype-core/support/Converters.d.ts +0 -6
- package/dist/quicktype-core/support/Converters.js +0 -16
- package/dist/quicktype-core/support/Strings.d.ts +0 -44
- package/dist/quicktype-core/support/Strings.js +0 -525
- package/dist/quicktype-core/support/Support.d.ts +0 -29
- package/dist/quicktype-core/support/Support.js +0 -162
- package/dist/quicktype-graphql-input/GraphQLSchema.d.ts +0 -645
- package/dist/quicktype-graphql-input/GraphQLSchema.js +0 -39
- package/dist/quicktype-graphql-input/index.d.ts +0 -17
- package/dist/quicktype-graphql-input/index.js +0 -407
- package/dist/quicktype-typescript-input/index.d.ts +0 -2
- package/dist/quicktype-typescript-input/index.js +0 -98
|
@@ -1,1211 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SwiftRenderer = exports.SwiftTargetLanguage = exports.swiftOptions = void 0;
|
|
4
|
-
const collection_utils_1 = require("collection-utils");
|
|
5
|
-
const Support_1 = require("../support/Support");
|
|
6
|
-
const TargetLanguage_1 = require("../TargetLanguage");
|
|
7
|
-
const Type_1 = require("../Type");
|
|
8
|
-
const TypeUtils_1 = require("../TypeUtils");
|
|
9
|
-
const Naming_1 = require("../Naming");
|
|
10
|
-
const RendererOptions_1 = require("../RendererOptions");
|
|
11
|
-
const Source_1 = require("../Source");
|
|
12
|
-
const Annotation_1 = require("../Annotation");
|
|
13
|
-
const ConvenienceRenderer_1 = require("../ConvenienceRenderer");
|
|
14
|
-
const Strings_1 = require("../support/Strings");
|
|
15
|
-
const Support_2 = require("../support/Support");
|
|
16
|
-
const DateTime_1 = require("../DateTime");
|
|
17
|
-
const Acronyms_1 = require("../support/Acronyms");
|
|
18
|
-
const MAX_SAMELINE_PROPERTIES = 4;
|
|
19
|
-
exports.swiftOptions = {
|
|
20
|
-
justTypes: new RendererOptions_1.BooleanOption("just-types", "Plain types only", false),
|
|
21
|
-
convenienceInitializers: new RendererOptions_1.BooleanOption("initializers", "Generate initializers and mutators", true),
|
|
22
|
-
explicitCodingKeys: new RendererOptions_1.BooleanOption("coding-keys", "Explicit CodingKey values in Codable types", true),
|
|
23
|
-
alamofire: new RendererOptions_1.BooleanOption("alamofire", "Alamofire extensions", false),
|
|
24
|
-
namedTypePrefix: new RendererOptions_1.StringOption("type-prefix", "Prefix for type names", "PREFIX", "", "secondary"),
|
|
25
|
-
useClasses: new RendererOptions_1.EnumOption("struct-or-class", "Structs or classes", [
|
|
26
|
-
["struct", false],
|
|
27
|
-
["class", true]
|
|
28
|
-
]),
|
|
29
|
-
mutableProperties: new RendererOptions_1.BooleanOption("mutable-properties", "Use var instead of let for object properties", false),
|
|
30
|
-
acronymStyle: (0, Acronyms_1.acronymOption)(Acronyms_1.AcronymStyleOptions.Pascal),
|
|
31
|
-
dense: new RendererOptions_1.EnumOption("density", "Code density", [
|
|
32
|
-
["dense", true],
|
|
33
|
-
["normal", false]
|
|
34
|
-
], "dense", "secondary"),
|
|
35
|
-
linux: new RendererOptions_1.BooleanOption("support-linux", "Support Linux", false, "secondary"),
|
|
36
|
-
objcSupport: new RendererOptions_1.BooleanOption("objective-c-support", "Objects inherit from NSObject and @objcMembers is added to classes", false),
|
|
37
|
-
optionalEnums: new RendererOptions_1.BooleanOption("optional-enums", "If no matching case is found enum value is set to null", false),
|
|
38
|
-
swift5Support: new RendererOptions_1.BooleanOption("swift-5-support", "Renders output in a Swift 5 compatible mode", false),
|
|
39
|
-
multiFileOutput: new RendererOptions_1.BooleanOption("multi-file-output", "Renders each top-level object in its own Swift file", false),
|
|
40
|
-
accessLevel: new RendererOptions_1.EnumOption("access-level", "Access level", [
|
|
41
|
-
["internal", "internal"],
|
|
42
|
-
["public", "public"]
|
|
43
|
-
], "internal", "secondary"),
|
|
44
|
-
protocol: new RendererOptions_1.EnumOption("protocol", "Make types implement protocol", [
|
|
45
|
-
["none", { equatable: false, hashable: false }],
|
|
46
|
-
["equatable", { equatable: true, hashable: false }],
|
|
47
|
-
["hashable", { equatable: false, hashable: true }]
|
|
48
|
-
], "none", "secondary")
|
|
49
|
-
};
|
|
50
|
-
// These are all recognized by Swift as ISO8601 date-times:
|
|
51
|
-
//
|
|
52
|
-
// 2018-08-14T02:45:50+00:00
|
|
53
|
-
// 2018-08-14T02:45:50+00
|
|
54
|
-
// 2018-08-14T02:45:50+1
|
|
55
|
-
// 2018-08-14T02:45:50+1111
|
|
56
|
-
// 2018-08-14T02:45:50+1111:1:33
|
|
57
|
-
// 2018-08-14T02:45:50-00
|
|
58
|
-
// 2018-08-14T02:45:50z
|
|
59
|
-
// 2018-00008-1T002:45:3Z
|
|
60
|
-
const swiftDateTimeRegex = /^\d+-\d+-\d+T\d+:\d+:\d+([zZ]|[+-]\d+(:\d+)?)$/;
|
|
61
|
-
class SwiftDateTimeRecognizer extends DateTime_1.DefaultDateTimeRecognizer {
|
|
62
|
-
isDateTime(str) {
|
|
63
|
-
return str.match(swiftDateTimeRegex) !== null;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
class SwiftTargetLanguage extends TargetLanguage_1.TargetLanguage {
|
|
67
|
-
constructor() {
|
|
68
|
-
super("Swift", ["swift", "swift4"], "swift");
|
|
69
|
-
}
|
|
70
|
-
getOptions() {
|
|
71
|
-
return [
|
|
72
|
-
exports.swiftOptions.justTypes,
|
|
73
|
-
exports.swiftOptions.useClasses,
|
|
74
|
-
exports.swiftOptions.dense,
|
|
75
|
-
exports.swiftOptions.convenienceInitializers,
|
|
76
|
-
exports.swiftOptions.explicitCodingKeys,
|
|
77
|
-
exports.swiftOptions.accessLevel,
|
|
78
|
-
exports.swiftOptions.alamofire,
|
|
79
|
-
exports.swiftOptions.linux,
|
|
80
|
-
exports.swiftOptions.namedTypePrefix,
|
|
81
|
-
exports.swiftOptions.protocol,
|
|
82
|
-
exports.swiftOptions.acronymStyle,
|
|
83
|
-
exports.swiftOptions.objcSupport,
|
|
84
|
-
exports.swiftOptions.optionalEnums,
|
|
85
|
-
exports.swiftOptions.swift5Support,
|
|
86
|
-
exports.swiftOptions.multiFileOutput,
|
|
87
|
-
exports.swiftOptions.mutableProperties
|
|
88
|
-
];
|
|
89
|
-
}
|
|
90
|
-
get stringTypeMapping() {
|
|
91
|
-
const mapping = new Map();
|
|
92
|
-
mapping.set("date-time", "date-time");
|
|
93
|
-
return mapping;
|
|
94
|
-
}
|
|
95
|
-
get supportsOptionalClassProperties() {
|
|
96
|
-
return true;
|
|
97
|
-
}
|
|
98
|
-
get supportsUnionsWithBothNumberTypes() {
|
|
99
|
-
return true;
|
|
100
|
-
}
|
|
101
|
-
makeRenderer(renderContext, untypedOptionValues) {
|
|
102
|
-
return new SwiftRenderer(this, renderContext, (0, RendererOptions_1.getOptionValues)(exports.swiftOptions, untypedOptionValues));
|
|
103
|
-
}
|
|
104
|
-
get dateTimeRecognizer() {
|
|
105
|
-
return new SwiftDateTimeRecognizer();
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
exports.SwiftTargetLanguage = SwiftTargetLanguage;
|
|
109
|
-
const keywords = [
|
|
110
|
-
"await",
|
|
111
|
-
"associatedtype",
|
|
112
|
-
"class",
|
|
113
|
-
"deinit",
|
|
114
|
-
"enum",
|
|
115
|
-
"extension",
|
|
116
|
-
"fileprivate",
|
|
117
|
-
"func",
|
|
118
|
-
"import",
|
|
119
|
-
"init",
|
|
120
|
-
"inout",
|
|
121
|
-
"internal",
|
|
122
|
-
"let",
|
|
123
|
-
"open",
|
|
124
|
-
"operator",
|
|
125
|
-
"private",
|
|
126
|
-
"protocol",
|
|
127
|
-
"public",
|
|
128
|
-
"static",
|
|
129
|
-
"struct",
|
|
130
|
-
"subscript",
|
|
131
|
-
"typealias",
|
|
132
|
-
"var",
|
|
133
|
-
"break",
|
|
134
|
-
"case",
|
|
135
|
-
"continue",
|
|
136
|
-
"default",
|
|
137
|
-
"defer",
|
|
138
|
-
"do",
|
|
139
|
-
"else",
|
|
140
|
-
"fallthrough",
|
|
141
|
-
"for",
|
|
142
|
-
"guard",
|
|
143
|
-
"if",
|
|
144
|
-
"in",
|
|
145
|
-
"repeat",
|
|
146
|
-
"return",
|
|
147
|
-
"switch",
|
|
148
|
-
"where",
|
|
149
|
-
"while",
|
|
150
|
-
"as",
|
|
151
|
-
"Any",
|
|
152
|
-
"catch",
|
|
153
|
-
"false",
|
|
154
|
-
"is",
|
|
155
|
-
"nil",
|
|
156
|
-
"rethrows",
|
|
157
|
-
"super",
|
|
158
|
-
"self",
|
|
159
|
-
"Self",
|
|
160
|
-
"throw",
|
|
161
|
-
"throws",
|
|
162
|
-
"true",
|
|
163
|
-
"try",
|
|
164
|
-
"_",
|
|
165
|
-
"associativity",
|
|
166
|
-
"convenience",
|
|
167
|
-
"dynamic",
|
|
168
|
-
"didSet",
|
|
169
|
-
"final",
|
|
170
|
-
"get",
|
|
171
|
-
"infix",
|
|
172
|
-
"indirect",
|
|
173
|
-
"lazy",
|
|
174
|
-
"left",
|
|
175
|
-
"mutating",
|
|
176
|
-
"nonmutating",
|
|
177
|
-
"optional",
|
|
178
|
-
"override",
|
|
179
|
-
"postfix",
|
|
180
|
-
"precedence",
|
|
181
|
-
"prefix",
|
|
182
|
-
"Protocol",
|
|
183
|
-
"required",
|
|
184
|
-
"right",
|
|
185
|
-
"set",
|
|
186
|
-
"Type",
|
|
187
|
-
"unowned",
|
|
188
|
-
"weak",
|
|
189
|
-
"willSet",
|
|
190
|
-
"String",
|
|
191
|
-
"Int",
|
|
192
|
-
"Double",
|
|
193
|
-
"Bool",
|
|
194
|
-
"Data",
|
|
195
|
-
"Date",
|
|
196
|
-
"URL",
|
|
197
|
-
"CommandLine",
|
|
198
|
-
"FileHandle",
|
|
199
|
-
"JSONSerialization",
|
|
200
|
-
"checkNull",
|
|
201
|
-
"removeNSNull",
|
|
202
|
-
"nilToNSNull",
|
|
203
|
-
"convertArray",
|
|
204
|
-
"convertOptional",
|
|
205
|
-
"convertDict",
|
|
206
|
-
"convertDouble",
|
|
207
|
-
"jsonString",
|
|
208
|
-
"jsonData"
|
|
209
|
-
];
|
|
210
|
-
function isPartCharacter(codePoint) {
|
|
211
|
-
return (0, Strings_1.isLetterOrUnderscore)(codePoint) || (0, Strings_1.isNumeric)(codePoint);
|
|
212
|
-
}
|
|
213
|
-
function isStartCharacter(codePoint) {
|
|
214
|
-
return isPartCharacter(codePoint) && !(0, Strings_1.isDigit)(codePoint);
|
|
215
|
-
}
|
|
216
|
-
const legalizeName = (0, Strings_1.legalizeCharacters)(isPartCharacter);
|
|
217
|
-
function swiftNameStyle(prefix, isUpper, original, acronymsStyle = Strings_1.allUpperWordStyle) {
|
|
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);
|
|
221
|
-
}
|
|
222
|
-
function unicodeEscape(codePoint) {
|
|
223
|
-
return "\\u{" + (0, Strings_1.intToHex)(codePoint, 0) + "}";
|
|
224
|
-
}
|
|
225
|
-
const stringEscape = (0, Strings_1.utf32ConcatMap)((0, Strings_1.escapeNonPrintableMapper)(Strings_1.isPrintable, unicodeEscape));
|
|
226
|
-
class SwiftRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
227
|
-
_options;
|
|
228
|
-
_currentFilename;
|
|
229
|
-
_needAny = false;
|
|
230
|
-
_needNull = false;
|
|
231
|
-
constructor(targetLanguage, renderContext, _options) {
|
|
232
|
-
super(targetLanguage, renderContext);
|
|
233
|
-
this._options = _options;
|
|
234
|
-
}
|
|
235
|
-
forbiddenNamesForGlobalNamespace() {
|
|
236
|
-
if (this._options.alamofire) {
|
|
237
|
-
return ["DataRequest", ...keywords];
|
|
238
|
-
}
|
|
239
|
-
return keywords;
|
|
240
|
-
}
|
|
241
|
-
forbiddenForObjectProperties(_c, _classNamed) {
|
|
242
|
-
return { names: ["fromURL", "json"], includeGlobalForbidden: true };
|
|
243
|
-
}
|
|
244
|
-
forbiddenForEnumCases(_e, _enumName) {
|
|
245
|
-
return { names: [], includeGlobalForbidden: true };
|
|
246
|
-
}
|
|
247
|
-
forbiddenForUnionMembers(_u, _unionName) {
|
|
248
|
-
return { names: [], includeGlobalForbidden: true };
|
|
249
|
-
}
|
|
250
|
-
makeNamedTypeNamer() {
|
|
251
|
-
return (0, Naming_1.funPrefixNamer)("upper", s => swiftNameStyle(this._options.namedTypePrefix, true, s, (0, Acronyms_1.acronymStyle)(this._options.acronymStyle)));
|
|
252
|
-
}
|
|
253
|
-
namerForObjectProperty() {
|
|
254
|
-
return this.lowerNamingFunction;
|
|
255
|
-
}
|
|
256
|
-
makeUnionMemberNamer() {
|
|
257
|
-
return this.lowerNamingFunction;
|
|
258
|
-
}
|
|
259
|
-
makeEnumCaseNamer() {
|
|
260
|
-
return this.lowerNamingFunction;
|
|
261
|
-
}
|
|
262
|
-
isImplicitCycleBreaker(t) {
|
|
263
|
-
const kind = t.kind;
|
|
264
|
-
return kind === "array" || kind === "map";
|
|
265
|
-
}
|
|
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), "?"];
|
|
289
|
-
}
|
|
290
|
-
else {
|
|
291
|
-
return this.swiftType(p.type, true);
|
|
292
|
-
}
|
|
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";
|
|
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";
|
|
319
|
-
}
|
|
320
|
-
if (kind === "union") {
|
|
321
|
-
return "one_of";
|
|
322
|
-
}
|
|
323
|
-
return null;
|
|
324
|
-
}
|
|
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);
|
|
341
|
-
}
|
|
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
|
-
}
|
|
371
|
-
}
|
|
372
|
-
this.ensureBlankLine();
|
|
373
|
-
this.emitLineOnce("import Foundation");
|
|
374
|
-
if (!this._options.justTypes && this._options.alamofire) {
|
|
375
|
-
this.emitLineOnce("import Alamofire");
|
|
376
|
-
}
|
|
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");
|
|
387
|
-
}
|
|
388
|
-
if (!this._options.justTypes) {
|
|
389
|
-
protocols.push("Codable");
|
|
390
|
-
}
|
|
391
|
-
if (this._options.protocol.hashable) {
|
|
392
|
-
protocols.push("Hashable");
|
|
393
|
-
}
|
|
394
|
-
if (this._options.protocol.equatable) {
|
|
395
|
-
protocols.push("Equatable");
|
|
396
|
-
}
|
|
397
|
-
return protocols;
|
|
398
|
-
}
|
|
399
|
-
getProtocolString(_t, isClass) {
|
|
400
|
-
const protocols = this.getProtocolsArray(_t, isClass);
|
|
401
|
-
return protocols.length > 0 ? ": " + protocols.join(", ") : "";
|
|
402
|
-
}
|
|
403
|
-
getEnumPropertyGroups(c) {
|
|
404
|
-
let groups = [];
|
|
405
|
-
let group = [];
|
|
406
|
-
this.forEachClassProperty(c, "none", (name, jsonName) => {
|
|
407
|
-
const label = stringEscape(jsonName);
|
|
408
|
-
const redundant = this.sourcelikeToString(name) === label;
|
|
409
|
-
if (this._options.dense && redundant) {
|
|
410
|
-
group.push({ name });
|
|
411
|
-
}
|
|
412
|
-
else {
|
|
413
|
-
if (group.length > 0) {
|
|
414
|
-
groups.push(group);
|
|
415
|
-
group = [];
|
|
416
|
-
}
|
|
417
|
-
groups.push([{ name, label }]);
|
|
418
|
-
}
|
|
419
|
-
});
|
|
420
|
-
if (group.length > 0) {
|
|
421
|
-
groups.push(group);
|
|
422
|
-
}
|
|
423
|
-
return groups;
|
|
424
|
-
}
|
|
425
|
-
/// Access level with trailing space (e.g. "public "), or empty string
|
|
426
|
-
get accessLevel() {
|
|
427
|
-
return this._options.accessLevel === "internal"
|
|
428
|
-
? "" // internal is default, so we don't have to emit it
|
|
429
|
-
: this._options.accessLevel + " ";
|
|
430
|
-
}
|
|
431
|
-
get objcMembersDeclaration() {
|
|
432
|
-
if (this._options.objcSupport) {
|
|
433
|
-
return "@objcMembers ";
|
|
434
|
-
}
|
|
435
|
-
return "";
|
|
436
|
-
}
|
|
437
|
-
/// startFile takes a file name, appends ".swift" to it and sets it as the current filename.
|
|
438
|
-
startFile(basename) {
|
|
439
|
-
if (this._options.multiFileOutput === false) {
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
(0, Support_1.assert)(this._currentFilename === undefined, "Previous file wasn't finished: " + this._currentFilename);
|
|
443
|
-
// FIXME: The filenames should actually be Sourcelikes, too
|
|
444
|
-
this._currentFilename = `${this.sourcelikeToString(basename)}.swift`;
|
|
445
|
-
this.initializeEmitContextForFilename(this._currentFilename);
|
|
446
|
-
}
|
|
447
|
-
/// endFile pushes the current file name onto the collection of finished files and then resets the current file name. These finished files are used in index.ts to write the output.
|
|
448
|
-
endFile() {
|
|
449
|
-
if (this._options.multiFileOutput === false) {
|
|
450
|
-
return;
|
|
451
|
-
}
|
|
452
|
-
this.finishFile((0, Support_1.defined)(this._currentFilename));
|
|
453
|
-
this._currentFilename = undefined;
|
|
454
|
-
}
|
|
455
|
-
propertyLinesDefinition(name, parameter) {
|
|
456
|
-
const useMutableProperties = this._options.mutableProperties;
|
|
457
|
-
return [
|
|
458
|
-
this.accessLevel,
|
|
459
|
-
useMutableProperties ? "var " : "let ",
|
|
460
|
-
name,
|
|
461
|
-
": ",
|
|
462
|
-
this.swiftPropertyType(parameter)
|
|
463
|
-
];
|
|
464
|
-
}
|
|
465
|
-
renderClassDefinition(c, className) {
|
|
466
|
-
this.startFile(className);
|
|
467
|
-
this.renderHeader(c, className);
|
|
468
|
-
this.emitDescription(this.descriptionForType(c));
|
|
469
|
-
this.emitMark(this.sourcelikeToString(className), true);
|
|
470
|
-
const isClass = this._options.useClasses || this.isCycleBreakerType(c);
|
|
471
|
-
const structOrClass = isClass ? "class" : "struct";
|
|
472
|
-
if (isClass && this._options.objcSupport) {
|
|
473
|
-
// [Michael Fey (@MrRooni), 2019-4-24] Swift 5 or greater, must come before the access declaration for the class.
|
|
474
|
-
this.emitItem(this.objcMembersDeclaration);
|
|
475
|
-
}
|
|
476
|
-
this.emitBlockWithAccess([structOrClass, " ", className, this.getProtocolString(c, isClass)], () => {
|
|
477
|
-
if (this._options.dense) {
|
|
478
|
-
let lastProperty = undefined;
|
|
479
|
-
let lastNames = [];
|
|
480
|
-
const emitLastProperty = () => {
|
|
481
|
-
if (lastProperty === undefined)
|
|
482
|
-
return;
|
|
483
|
-
const useMutableProperties = this._options.mutableProperties;
|
|
484
|
-
let sources = [
|
|
485
|
-
[
|
|
486
|
-
this._options.optionalEnums && lastProperty.type.kind === "enum"
|
|
487
|
-
? `@NilOnFail${this._options.namedTypePrefix} `
|
|
488
|
-
: "",
|
|
489
|
-
this.accessLevel,
|
|
490
|
-
useMutableProperties || (this._options.optionalEnums && lastProperty.type.kind === "enum")
|
|
491
|
-
? "var "
|
|
492
|
-
: "let "
|
|
493
|
-
]
|
|
494
|
-
];
|
|
495
|
-
lastNames.forEach((n, i) => {
|
|
496
|
-
if (i > 0)
|
|
497
|
-
sources.push(", ");
|
|
498
|
-
sources.push(n);
|
|
499
|
-
});
|
|
500
|
-
sources.push(": ");
|
|
501
|
-
sources.push(this.swiftPropertyType(lastProperty));
|
|
502
|
-
this.emitLine(sources);
|
|
503
|
-
lastProperty = undefined;
|
|
504
|
-
lastNames = [];
|
|
505
|
-
};
|
|
506
|
-
this.forEachClassProperty(c, "none", (name, jsonName, p) => {
|
|
507
|
-
const description = this.descriptionForClassProperty(c, jsonName);
|
|
508
|
-
if (!p.equals(lastProperty) ||
|
|
509
|
-
lastNames.length >= MAX_SAMELINE_PROPERTIES ||
|
|
510
|
-
description !== undefined) {
|
|
511
|
-
emitLastProperty();
|
|
512
|
-
}
|
|
513
|
-
if (lastProperty === undefined) {
|
|
514
|
-
lastProperty = p;
|
|
515
|
-
}
|
|
516
|
-
lastNames.push(name);
|
|
517
|
-
if (description !== undefined) {
|
|
518
|
-
this.emitDescription(description);
|
|
519
|
-
emitLastProperty();
|
|
520
|
-
}
|
|
521
|
-
});
|
|
522
|
-
emitLastProperty();
|
|
523
|
-
}
|
|
524
|
-
else {
|
|
525
|
-
this.forEachClassProperty(c, "none", (name, jsonName, p) => {
|
|
526
|
-
const description = this.descriptionForClassProperty(c, jsonName);
|
|
527
|
-
const propertyLines = this.propertyLinesDefinition(name, p);
|
|
528
|
-
this.emitDescription(description);
|
|
529
|
-
this.emitLine(propertyLines);
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
|
-
if (!this._options.justTypes) {
|
|
533
|
-
const groups = this.getEnumPropertyGroups(c);
|
|
534
|
-
const allPropertiesRedundant = groups.every(group => {
|
|
535
|
-
return group.every(p => p.label === undefined);
|
|
536
|
-
});
|
|
537
|
-
if (!allPropertiesRedundant && c.getProperties().size > 0) {
|
|
538
|
-
this.ensureBlankLine();
|
|
539
|
-
this.emitBlock("enum CodingKeys: String, CodingKey", () => {
|
|
540
|
-
for (const group of groups) {
|
|
541
|
-
const { name, label } = group[0];
|
|
542
|
-
if (this._options.explicitCodingKeys && label !== undefined) {
|
|
543
|
-
this.emitLine("case ", name, ' = "', label, '"');
|
|
544
|
-
}
|
|
545
|
-
else {
|
|
546
|
-
const names = (0, collection_utils_1.arrayIntercalate)(", ", group.map(p => p.name));
|
|
547
|
-
this.emitLine("case ", names);
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
// this main initializer must be defined within the class
|
|
554
|
-
// declaration since it assigns let constants
|
|
555
|
-
if (isClass ||
|
|
556
|
-
// Public structs need explicit initializers
|
|
557
|
-
// https://github.com/quicktype/quicktype/issues/899
|
|
558
|
-
this._options.accessLevel === "public") {
|
|
559
|
-
// Make an initializer that initalizes all fields
|
|
560
|
-
this.ensureBlankLine();
|
|
561
|
-
let initProperties = this.initializableProperties(c);
|
|
562
|
-
let propertiesLines = [];
|
|
563
|
-
for (let property of initProperties) {
|
|
564
|
-
if (propertiesLines.length > 0)
|
|
565
|
-
propertiesLines.push(", ");
|
|
566
|
-
propertiesLines.push(property.name, ": ", this.swiftPropertyType(property.parameter));
|
|
567
|
-
}
|
|
568
|
-
if (this.propertyCount(c) === 0 && this._options.objcSupport) {
|
|
569
|
-
this.emitBlockWithAccess(["override init()"], () => {
|
|
570
|
-
return "";
|
|
571
|
-
});
|
|
572
|
-
}
|
|
573
|
-
else {
|
|
574
|
-
this.emitBlockWithAccess(["init(", ...propertiesLines, ")"], () => {
|
|
575
|
-
for (let property of initProperties) {
|
|
576
|
-
this.emitLine("self.", property.name, " = ", property.name);
|
|
577
|
-
}
|
|
578
|
-
});
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
});
|
|
582
|
-
if (!this._options.justTypes) {
|
|
583
|
-
// FIXME: We emit only the MARK line for top-level-enum.schema
|
|
584
|
-
if (this._options.convenienceInitializers) {
|
|
585
|
-
this.ensureBlankLine();
|
|
586
|
-
this.emitMark(this.sourcelikeToString(className) + " convenience initializers and mutators");
|
|
587
|
-
this.ensureBlankLine();
|
|
588
|
-
this.emitConvenienceInitializersExtension(c, className);
|
|
589
|
-
this.ensureBlankLine();
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
this.endFile();
|
|
593
|
-
}
|
|
594
|
-
initializableProperties(c) {
|
|
595
|
-
const properties = [];
|
|
596
|
-
this.forEachClassProperty(c, "none", (name, jsonName, parameter, position) => {
|
|
597
|
-
const property = { name, jsonName, parameter, position };
|
|
598
|
-
properties.push(property);
|
|
599
|
-
});
|
|
600
|
-
return properties;
|
|
601
|
-
}
|
|
602
|
-
emitNewEncoderDecoder() {
|
|
603
|
-
this.emitBlock("func newJSONDecoder() -> JSONDecoder", () => {
|
|
604
|
-
this.emitLine("let decoder = JSONDecoder()");
|
|
605
|
-
if (!this._options.linux) {
|
|
606
|
-
this.emitBlock("if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *)", () => {
|
|
607
|
-
this.emitLine("decoder.dateDecodingStrategy = .iso8601");
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
else {
|
|
611
|
-
this.emitMultiline(`decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in
|
|
612
|
-
let container = try decoder.singleValueContainer()
|
|
613
|
-
let dateStr = try container.decode(String.self)
|
|
614
|
-
|
|
615
|
-
let formatter = DateFormatter()
|
|
616
|
-
formatter.calendar = Calendar(identifier: .iso8601)
|
|
617
|
-
formatter.locale = Locale(identifier: "en_US_POSIX")
|
|
618
|
-
formatter.timeZone = TimeZone(secondsFromGMT: 0)
|
|
619
|
-
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
|
|
620
|
-
if let date = formatter.date(from: dateStr) {
|
|
621
|
-
return date
|
|
622
|
-
}
|
|
623
|
-
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXXXX"
|
|
624
|
-
if let date = formatter.date(from: dateStr) {
|
|
625
|
-
return date
|
|
626
|
-
}
|
|
627
|
-
throw DecodingError.typeMismatch(Date.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Could not decode date"))
|
|
628
|
-
})`);
|
|
629
|
-
}
|
|
630
|
-
this.emitLine("return decoder");
|
|
631
|
-
});
|
|
632
|
-
this.ensureBlankLine();
|
|
633
|
-
this.emitBlock("func newJSONEncoder() -> JSONEncoder", () => {
|
|
634
|
-
this.emitLine("let encoder = JSONEncoder()");
|
|
635
|
-
if (!this._options.linux) {
|
|
636
|
-
this.emitBlock("if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *)", () => {
|
|
637
|
-
this.emitLine("encoder.dateEncodingStrategy = .iso8601");
|
|
638
|
-
});
|
|
639
|
-
}
|
|
640
|
-
else {
|
|
641
|
-
this.emitMultiline(`let formatter = DateFormatter()
|
|
642
|
-
formatter.calendar = Calendar(identifier: .iso8601)
|
|
643
|
-
formatter.locale = Locale(identifier: "en_US_POSIX")
|
|
644
|
-
formatter.timeZone = TimeZone(secondsFromGMT: 0)
|
|
645
|
-
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXXXX"
|
|
646
|
-
encoder.dateEncodingStrategy = .formatted(formatter)`);
|
|
647
|
-
}
|
|
648
|
-
this.emitLine("return encoder");
|
|
649
|
-
});
|
|
650
|
-
}
|
|
651
|
-
emitConvenienceInitializersExtension(c, className) {
|
|
652
|
-
const isClass = this._options.useClasses || this.isCycleBreakerType(c);
|
|
653
|
-
const convenience = isClass ? "convenience " : "";
|
|
654
|
-
this.emitBlockWithAccess(["extension ", className], () => {
|
|
655
|
-
if (isClass) {
|
|
656
|
-
this.emitBlock("convenience init(data: Data) throws", () => {
|
|
657
|
-
if (this.propertyCount(c) > 0) {
|
|
658
|
-
this.emitLine("let me = try newJSONDecoder().decode(", this.swiftType(c), ".self, from: data)");
|
|
659
|
-
}
|
|
660
|
-
else {
|
|
661
|
-
this.emitLine("let _ = try newJSONDecoder().decode(", this.swiftType(c), ".self, from: data)");
|
|
662
|
-
}
|
|
663
|
-
let args = [];
|
|
664
|
-
this.forEachClassProperty(c, "none", name => {
|
|
665
|
-
if (args.length > 0)
|
|
666
|
-
args.push(", ");
|
|
667
|
-
args.push(name, ": ", "me.", name);
|
|
668
|
-
});
|
|
669
|
-
this.emitLine("self.init(", ...args, ")");
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
|
-
else {
|
|
673
|
-
this.emitBlock("init(data: Data) throws", () => {
|
|
674
|
-
this.emitLine("self = try newJSONDecoder().decode(", this.swiftType(c), ".self, from: data)");
|
|
675
|
-
});
|
|
676
|
-
}
|
|
677
|
-
this.ensureBlankLine();
|
|
678
|
-
this.emitBlock([convenience, "init(_ json: String, using encoding: String.Encoding = .utf8) throws"], () => {
|
|
679
|
-
this.emitBlock("guard let data = json.data(using: encoding) else", () => {
|
|
680
|
-
this.emitLine(`throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)`);
|
|
681
|
-
});
|
|
682
|
-
this.emitLine("try self.init(data: data)");
|
|
683
|
-
});
|
|
684
|
-
this.ensureBlankLine();
|
|
685
|
-
this.emitBlock([convenience, `init(fromURL url: URL) throws`], () => {
|
|
686
|
-
this.emitLine("try self.init(data: try Data(contentsOf: url))");
|
|
687
|
-
});
|
|
688
|
-
this.ensureBlankLine();
|
|
689
|
-
this.emitConvenienceMutator(c, className);
|
|
690
|
-
// Convenience serializers
|
|
691
|
-
this.ensureBlankLine();
|
|
692
|
-
this.emitBlock(`func jsonData() throws -> Data`, () => {
|
|
693
|
-
this.emitLine("return try newJSONEncoder().encode(self)");
|
|
694
|
-
});
|
|
695
|
-
this.ensureBlankLine();
|
|
696
|
-
this.emitBlock(`func jsonString(encoding: String.Encoding = .utf8) throws -> String?`, () => {
|
|
697
|
-
this.emitLine("return String(data: try self.jsonData(), encoding: encoding)");
|
|
698
|
-
});
|
|
699
|
-
});
|
|
700
|
-
}
|
|
701
|
-
renderEnumDefinition(e, enumName) {
|
|
702
|
-
this.startFile(enumName);
|
|
703
|
-
this.emitLineOnce("import Foundation");
|
|
704
|
-
this.ensureBlankLine();
|
|
705
|
-
this.emitDescription(this.descriptionForType(e));
|
|
706
|
-
const protocols = [];
|
|
707
|
-
if (!this._options.justTypes) {
|
|
708
|
-
protocols.push("String"); // Not a protocol
|
|
709
|
-
protocols.push("Codable");
|
|
710
|
-
}
|
|
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
|
|
979
|
-
}
|
|
980
|
-
if let value = try? container.decode(String.self) {
|
|
981
|
-
return value
|
|
982
|
-
}
|
|
983
|
-
if let value = try? container.decodeNil() {
|
|
984
|
-
if value {
|
|
985
|
-
return JSONNull()
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
if var container = try? container.nestedUnkeyedContainer() {
|
|
989
|
-
return try decodeArray(from: &container)
|
|
990
|
-
}
|
|
991
|
-
if var container = try? container.nestedContainer(keyedBy: JSONCodingKey.self) {
|
|
992
|
-
return try decodeDictionary(from: &container)
|
|
993
|
-
}
|
|
994
|
-
throw decodingError(forCodingPath: container.codingPath)
|
|
995
|
-
}
|
|
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
|
|
1000
|
-
}
|
|
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()
|
|
1013
|
-
}
|
|
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)
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
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
|
-
}
|
|
1088
|
-
}
|
|
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)
|
|
1104
|
-
}
|
|
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)
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
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
|
-
}
|
|
1129
|
-
}
|
|
1130
|
-
}`);
|
|
1131
|
-
}
|
|
1132
|
-
this.endFile();
|
|
1133
|
-
};
|
|
1134
|
-
emitConvenienceMutator(c, className) {
|
|
1135
|
-
this.emitLine("func with(");
|
|
1136
|
-
this.indent(() => {
|
|
1137
|
-
this.forEachClassProperty(c, "none", (name, _, p, position) => {
|
|
1138
|
-
this.emitLine(name, ": ", this.swiftPropertyType(p), "? = nil", position !== "only" && position !== "last" ? "," : "");
|
|
1139
|
-
});
|
|
1140
|
-
});
|
|
1141
|
-
this.emitBlock([") -> ", className], () => {
|
|
1142
|
-
this.emitLine("return ", className, "(");
|
|
1143
|
-
this.indent(() => {
|
|
1144
|
-
this.forEachClassProperty(c, "none", (name, _, _p, position) => {
|
|
1145
|
-
this.emitLine(name, ": ", name, " ?? self.", name, position !== "only" && position !== "last" ? "," : "");
|
|
1146
|
-
});
|
|
1147
|
-
});
|
|
1148
|
-
this.emitLine(")");
|
|
1149
|
-
});
|
|
1150
|
-
}
|
|
1151
|
-
emitMark(line, horizontalLine = false) {
|
|
1152
|
-
this.emitLine("// MARK:", horizontalLine ? " - " : " ", line);
|
|
1153
|
-
}
|
|
1154
|
-
emitSourceStructure() {
|
|
1155
|
-
if (this._options.multiFileOutput === false) {
|
|
1156
|
-
this.renderSingleFileHeaderComments();
|
|
1157
|
-
}
|
|
1158
|
-
this.forEachNamedType("leading-and-interposing", (c, className) => this.renderClassDefinition(c, className), (e, enumName) => this.renderEnumDefinition(e, enumName), (u, unionName) => this.renderUnionDefinition(u, unionName));
|
|
1159
|
-
if (!this._options.justTypes) {
|
|
1160
|
-
this.emitSupportFunctions4();
|
|
1161
|
-
}
|
|
1162
|
-
if (this._options.optionalEnums) {
|
|
1163
|
-
this.emitBlockWithAccess(`@propertyWrapper public struct NilOnFail${this._options.namedTypePrefix}<T: Codable>: Codable`, () => {
|
|
1164
|
-
this.emitMultiline(`
|
|
1165
|
-
public let wrappedValue: T?
|
|
1166
|
-
public init(from decoder: Decoder) throws {
|
|
1167
|
-
wrappedValue = try? T(from: decoder)
|
|
1168
|
-
}
|
|
1169
|
-
public init(_ wrappedValue: T?) {
|
|
1170
|
-
self.wrappedValue = wrappedValue
|
|
1171
|
-
}`);
|
|
1172
|
-
});
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
emitAlamofireExtension() {
|
|
1176
|
-
this.ensureBlankLine();
|
|
1177
|
-
this.emitBlockWithAccess("extension DataRequest", () => {
|
|
1178
|
-
this
|
|
1179
|
-
.emitMultiline(`fileprivate func decodableResponseSerializer<T: Decodable>() -> DataResponseSerializer<T> {
|
|
1180
|
-
return DataResponseSerializer { _, response, data, error in
|
|
1181
|
-
guard error == nil else { return .failure(error!) }
|
|
1182
|
-
|
|
1183
|
-
guard let data = data else {
|
|
1184
|
-
return .failure(AFError.responseSerializationFailed(reason: .inputDataNil))
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
return Result { try newJSONDecoder().decode(T.self, from: data) }
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
@discardableResult
|
|
1192
|
-
fileprivate func responseDecodable<T: Decodable>(queue: DispatchQueue? = nil, completionHandler: @escaping (DataResponse<T>) -> Void) -> Self {
|
|
1193
|
-
return response(queue: queue, responseSerializer: decodableResponseSerializer(), completionHandler: completionHandler)
|
|
1194
|
-
}`);
|
|
1195
|
-
this.ensureBlankLine();
|
|
1196
|
-
this.forEachTopLevel("leading-and-interposing", (_, name) => {
|
|
1197
|
-
this.emitLine("@discardableResult");
|
|
1198
|
-
this.emitBlock([
|
|
1199
|
-
"func response",
|
|
1200
|
-
name,
|
|
1201
|
-
"(queue: DispatchQueue? = nil, completionHandler: @escaping (DataResponse<",
|
|
1202
|
-
name,
|
|
1203
|
-
">) -> Void) -> Self"
|
|
1204
|
-
], () => {
|
|
1205
|
-
this.emitLine(`return responseDecodable(queue: queue, completionHandler: completionHandler)`);
|
|
1206
|
-
});
|
|
1207
|
-
});
|
|
1208
|
-
});
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
exports.SwiftRenderer = SwiftRenderer;
|