[swift5] support both date and date-time formats (#13520)

* add withoutTime formatter

* add DateWithoutTime

wip

* fix CI

# Conflicts:
#	samples/client/petstore/swift5/nonPublicApi/PetstoreClient/Classes/OpenAPIs/DateWithoutTime.swift

* implement flag and adjust tests

* generate samples and docs

* docs

* update samples

* remove samples of legacy python generator

* Revert "remove samples of legacy python generator"

This reverts commit 28da78f99dcaa6cf761367b0a2d2c3fddf4803ec.

* review remarks

* generate samples

* fix

* review remarks

* remove samples

* generate swift 5 samples

* generate csharp examples

* docs

* Revert "generate csharp examples"

This reverts commit d1deb17dbcd04b9b00d9ad4a08ce55bedd960de8.

* Revert "generate swift 5 samples"

This reverts commit 968e859bfe3ce631f174d10f10983ed2f5c09486.

* Revert "remove samples"

This reverts commit a43d21529ba6a9e615671729d970ec7ef9662402.

* manually remove FILES

* regenerate files

* reviewers remarks

* delete all date without times

* update config of alamofireLib to use new attribute and generate samples again

* docs
This commit is contained in:
Jonas Reichert 2022-09-26 18:39:35 +02:00 committed by GitHub
parent de745a4c61
commit 22086e4f3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 519 additions and 30 deletions

View File

@ -4,6 +4,7 @@ library: alamofire
inputSpec: modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/swift5
generateAliasAsModel: true
useCustomDateWithoutTime: true
additionalProperties:
podAuthors: ""
podSummary: PetstoreClient

View File

@ -53,6 +53,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|swiftUseApiNamespace|Flag to make all the API classes inner-class of {{projectName}}API| |null|
|useBacktickEscapes|Escape reserved words using backticks (default: false)| |false|
|useClasses|Use final classes for models instead of structs (default: false)| |false|
|useCustomDateWithoutTime|Uses a custom type to decode and encode dates without time information to support OpenAPIs date format (default: false)| |false|
|useJsonEncodable|Make models conform to JSONEncodable protocol (default: true)| |true|
|useSPMFileStructure|Use SPM file structure and set the source path to Sources/{{projectName}} (default: false).| |null|
@ -83,6 +84,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>Int</li>
<li>Int32</li>
<li>Int64</li>
<li>OpenAPIDateWithoutTime</li>
<li>String</li>
<li>URL</li>
<li>UUID</li>

View File

@ -72,6 +72,7 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
public static final String HASHABLE_MODELS = "hashableModels";
public static final String USE_JSON_ENCODABLE = "useJsonEncodable";
public static final String MAP_FILE_BINARY_TO_DATA = "mapFileBinaryToData";
public static final String USE_CUSTOM_DATE_WITHOUT_TIME = "useCustomDateWithoutTime";
protected static final String LIBRARY_ALAMOFIRE = "alamofire";
protected static final String LIBRARY_URLSESSION = "urlsession";
protected static final String LIBRARY_VAPOR = "vapor";
@ -96,6 +97,7 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
protected boolean hashableModels = true;
protected boolean useJsonEncodable = true;
protected boolean mapFileBinaryToData = false;
protected boolean useCustomDateWithoutTime = false;
protected String[] responseAs = new String[0];
protected String sourceFolder = swiftPackagePath;
protected HashSet objcReservedWords;
@ -134,6 +136,7 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
"String",
"Data",
"Date",
"OpenAPIDateWithoutTime",
"Character",
"UUID",
"URL",
@ -221,7 +224,6 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
typeMapping.put("array", "Array");
typeMapping.put("map", "Dictionary");
typeMapping.put("set", "Set");
typeMapping.put("date", "Date");
typeMapping.put("Date", "Date");
typeMapping.put("DateTime", "Date");
typeMapping.put("boolean", "Bool");
@ -309,6 +311,10 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
"[WARNING] This option will be removed and enabled by default in the future once we've enhanced the code to work with `Data` in all the different situations. Map File and Binary to Data (default: false)")
.defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(USE_CUSTOM_DATE_WITHOUT_TIME,
"Uses a custom type to decode and encode dates without time information to support OpenAPIs date format (default: false)")
.defaultValue(Boolean.FALSE.toString()));
supportedLibraries.put(LIBRARY_URLSESSION, "[DEFAULT] HTTP client: URLSession");
supportedLibraries.put(LIBRARY_ALAMOFIRE, "HTTP client: Alamofire");
supportedLibraries.put(LIBRARY_VAPOR, "HTTP client: Vapor");
@ -517,6 +523,16 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
typeMapping.put("binary", "Data");
}
if (additionalProperties.containsKey(USE_CUSTOM_DATE_WITHOUT_TIME)) {
setUseCustomDateWithoutTime(convertPropertyToBooleanAndWriteBack(USE_CUSTOM_DATE_WITHOUT_TIME));
}
additionalProperties.put(USE_CUSTOM_DATE_WITHOUT_TIME, useCustomDateWithoutTime);
if (useCustomDateWithoutTime) {
typeMapping.put("date", "OpenAPIDateWithoutTime");
} else {
typeMapping.put("date", "Date");
}
if (additionalProperties.containsKey(USE_CLASSES)) {
setUseClasses(convertPropertyToBooleanAndWriteBack(USE_CLASSES));
}
@ -538,9 +554,6 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
supportingFiles.add(new SupportingFile("CodableHelper.mustache",
sourceFolder,
"CodableHelper.swift"));
supportingFiles.add(new SupportingFile("OpenISO8601DateFormatter.mustache",
sourceFolder,
"OpenISO8601DateFormatter.swift"));
supportingFiles.add(new SupportingFile("JSONDataEncoding.mustache",
sourceFolder,
"JSONDataEncoding.swift"));
@ -572,6 +585,14 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
supportingFiles.add(new SupportingFile("Extensions.mustache",
sourceFolder,
"Extensions.swift"));
supportingFiles.add(new SupportingFile("OpenISO8601DateFormatter.mustache",
sourceFolder,
"OpenISO8601DateFormatter.swift"));
if (useCustomDateWithoutTime) {
supportingFiles.add(new SupportingFile("OpenAPIDateWithoutTime.mustache",
sourceFolder,
"OpenAPIDateWithoutTime.swift"));
}
supportingFiles.add(new SupportingFile("APIs.mustache",
sourceFolder,
"APIs.swift"));
@ -615,6 +636,10 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
this.mapFileBinaryToData = mapFileBinaryToData;
}
public void setUseCustomDateWithoutTime(boolean useCustomDateWithoutTime) {
this.useCustomDateWithoutTime = useCustomDateWithoutTime;
}
@Override
protected boolean isReservedWord(String word) {
return word != null && reservedWords.contains(word); //don't lowercase as super does

View File

@ -0,0 +1,69 @@
// OpenAPIDateWithoutTime.swift
//
// Generated by openapi-generator
// https://openapi-generator.tech
//
import Foundation
/// Represents a date without time information (e.g. a birthday) for transmission from and to a REST API
///
/// This type is used as a representation for openapi specs `date` format which does not contain
/// time information as opposed to the `date-time` format. Although it internally uses `Date` for
/// (de-)serialization as well the generator needs to be able to distinguish between the two formats.
/// - note: As `Date` is agnostic to timezones (and calendars), timezone information is needed to be able to add
/// an appropriate padding in order to transform to GMT+0 which is the assumed timezone in ISO 8601.
/// When decoding, GMT+0 can be assumed (again: ISO8601) so there is no padding necessary and wrappedDate
/// can be used safely.
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} struct OpenAPIDateWithoutTime: Codable, Hashable, Equatable {
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} let wrappedDate: Date
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} let timezone: TimeZone
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} enum CodingKeys: CodingKey, CaseIterable {
case wrappedDate
case timezone
}
/// On decoding ISO8601 timezone is assumed
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
self.wrappedDate = try container.decode(Date.self)
self.timezone = OpenISO8601DateFormatter.withoutTime.timeZone
}
/// Convenience Initializer which is useful when dealing with optionals a lot like e.g. in API mappers
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} init?(wrappedDate: Date?, timezone: TimeZone = .current) {
guard let wrappedDate = wrappedDate else {
return nil
}
self.init(wrappedDate: wrappedDate, timezone: timezone)
}
/// Designated Initializer for `OpenAPIDateWithoutTime`
///
/// Since usually `Date`s without time components - as e.g. birthdays - are created Calendar- and timezone-aware
// it is important to also provide a timezone so that the generator is able to normalize the supplied Date to ISO8601 (GMT+0)
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} init(wrappedDate: Date, timezone: TimeZone) {
self.wrappedDate = wrappedDate
self.timezone = timezone
}
/// Only the wrappedDate is encoded normalized to GMT+0 with an offset derived from the supplied Timezone
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(OpenISO8601DateFormatter.withoutTime.string(from: normalizedWrappedDate()))
}
/// Normalizes the wrappedDate to GMT+0 according to the supplied timezone
fileprivate func normalizedWrappedDate() -> Date {
return wrappedDate.addingTimeInterval(
Double(timezone.secondsFromGMT(for: wrappedDate)))
}
}
extension OpenAPIDateWithoutTime: JSONEncodable {
func encodeToJSON() -> Any {
return OpenISO8601DateFormatter.withoutTime.string(from: self.normalizedWrappedDate())
}
}

View File

@ -18,6 +18,15 @@ import Foundation
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ import Foundation
override {{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -101,6 +101,7 @@ public class Swift5OptionsProvider implements OptionsProvider {
.put(Swift5ClientCodegen.HASHABLE_MODELS, HASHABLE_MODELS_VALUE)
.put(Swift5ClientCodegen.USE_JSON_ENCODABLE, USE_JSON_ENCODABLE_VALUE)
.put(Swift5ClientCodegen.MAP_FILE_BINARY_TO_DATA, "false")
.put(Swift5ClientCodegen.USE_CUSTOM_DATE_WITHOUT_TIME, "false")
.put(Swift5ClientCodegen.USE_CLASSES, "false")
.put(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE, ENUM_UNKNOWN_DEFAULT_CASE_VALUE)
.build();

View File

@ -122,8 +122,8 @@ public class Swift5ClientCodegenTest {
Assert.assertTrue(op.responses.get(0).isBinary);
}
@Test(description = "returns Date when response format is date", enabled = true)
public void dateTest() {
@Test(description = "returns Date when response format is date per default", enabled = true)
public void dateDefaultTest() {
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/2_0/datePropertyTest.json");
final DefaultCodegen codegen = new Swift5ClientCodegen();
codegen.setOpenAPI(openAPI);
@ -135,6 +135,37 @@ public class Swift5ClientCodegenTest {
Assert.assertEquals(op.bodyParam.dataType, "Date");
}
@Test(description = "returns Date when response format is date and cli option is disabled", enabled = true)
public void dateDisabledCLITest() {
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/2_0/datePropertyTest.json");
final DefaultCodegen codegen = new Swift5ClientCodegen();
codegen.setOpenAPI(openAPI);
codegen.additionalProperties().put(Swift5ClientCodegen.USE_CUSTOM_DATE_WITHOUT_TIME, false);
codegen.processOpts();
final String path = "/tests/dateResponse";
final Operation p = openAPI.getPaths().get(path).getPost();
final CodegenOperation op = codegen.fromOperation(path, "post", p, null);
Assert.assertEquals(op.returnType, "Date");
Assert.assertEquals(op.bodyParam.dataType, "Date");
}
@Test(description = "returns OpenAPIDateWithoutTime when response format is date and cli option is enabled", enabled = true)
public void dateWithoutTimeTest() {
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/2_0/datePropertyTest.json");
final DefaultCodegen codegen = new Swift5ClientCodegen();
codegen.setOpenAPI(openAPI);
codegen.additionalProperties().put(Swift5ClientCodegen.USE_CUSTOM_DATE_WITHOUT_TIME, true);
codegen.processOpts();
final String path = "/tests/dateResponse";
final Operation p = openAPI.getPaths().get(path).getPost();
final CodegenOperation op = codegen.fromOperation(path, "post", p, null);
Assert.assertEquals(op.returnType, "OpenAPIDateWithoutTime");
Assert.assertEquals(op.bodyParam.dataType, "OpenAPIDateWithoutTime");
}
@Test(enabled = true)
public void testDefaultPodAuthors() throws Exception {
// Given

View File

@ -122,4 +122,45 @@ public class Swift5ModelTest {
Assert.assertFalse(property7.isContainer);
}
@Test(description = "convert a simple java model", enabled = true)
public void useCustomDateTimeTest() {
final Schema schema = new Schema()
.description("a sample model")
.addProperties("id", new IntegerSchema().format(SchemaTypeUtil.INTEGER64_FORMAT))
.addProperties("name", new StringSchema())
.addProperties("createdAt", new DateTimeSchema())
.addProperties("binary", new BinarySchema())
.addProperties("byte", new ByteArraySchema())
.addProperties("uuid", new UUIDSchema())
.addProperties("dateOfBirth", new DateSchema())
.addRequiredItem("id")
.addRequiredItem("name")
.discriminator(new Discriminator().propertyName("test"));
final DefaultCodegen codegen = new Swift5ClientCodegen();
OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", schema);
codegen.setOpenAPI(openAPI);
codegen.additionalProperties().put(Swift5ClientCodegen.USE_CUSTOM_DATE_WITHOUT_TIME, true);
codegen.processOpts();
final CodegenModel cm = codegen.fromModel("sample", schema);
final CodegenProperty property7 = cm.vars.get(6);
final CodegenProperty property3 = cm.vars.get(2);
Assert.assertEquals(property3.baseName, "createdAt");
Assert.assertEquals(property3.dataType, "Date");
Assert.assertEquals(property3.name, "createdAt");
Assert.assertNull(property3.defaultValue);
Assert.assertEquals(property3.baseType, "Date");
Assert.assertFalse(property3.required);
Assert.assertFalse(property3.isContainer);
Assert.assertEquals(property7.baseName, "dateOfBirth");
Assert.assertEquals(property7.dataType, "OpenAPIDateWithoutTime");
Assert.assertEquals(property7.name, "dateOfBirth");
Assert.assertNull(property7.defaultValue);
Assert.assertEquals(property7.baseType, "OpenAPIDateWithoutTime");
Assert.assertFalse(property7.required);
Assert.assertFalse(property7.isContainer);
}
}

View File

@ -58,6 +58,7 @@ PetstoreClient/Classes/OpenAPIs/Models/Tag.swift
PetstoreClient/Classes/OpenAPIs/Models/TypeHolderDefault.swift
PetstoreClient/Classes/OpenAPIs/Models/TypeHolderExample.swift
PetstoreClient/Classes/OpenAPIs/Models/User.swift
PetstoreClient/Classes/OpenAPIs/OpenAPIDateWithoutTime.swift
PetstoreClient/Classes/OpenAPIs/OpenISO8601DateFormatter.swift
PetstoreClient/Classes/OpenAPIs/SynchronizedDictionary.swift
README.md

View File

@ -333,7 +333,7 @@ open class FakeAPI {
- parameter completion: completion handler to receive the data and the error objects
*/
@discardableResult
open class func testEndpointParameters(number: Double, double: Double, patternWithoutDelimiter: String, byte: Data, integer: Int? = nil, int32: Int? = nil, int64: Int64? = nil, float: Float? = nil, string: String? = nil, binary: URL? = nil, date: Date? = nil, dateTime: Date? = nil, password: String? = nil, callback: String? = nil, apiResponseQueue: DispatchQueue = PetstoreClientAPI.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> RequestTask {
open class func testEndpointParameters(number: Double, double: Double, patternWithoutDelimiter: String, byte: Data, integer: Int? = nil, int32: Int? = nil, int64: Int64? = nil, float: Float? = nil, string: String? = nil, binary: URL? = nil, date: OpenAPIDateWithoutTime? = nil, dateTime: Date? = nil, password: String? = nil, callback: String? = nil, apiResponseQueue: DispatchQueue = PetstoreClientAPI.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> RequestTask {
return testEndpointParametersWithRequestBuilder(number: number, double: double, patternWithoutDelimiter: patternWithoutDelimiter, byte: byte, integer: integer, int32: int32, int64: int64, float: float, string: string, binary: binary, date: date, dateTime: dateTime, password: password, callback: callback).execute(apiResponseQueue) { result in
switch result {
case .success:
@ -367,7 +367,7 @@ open class FakeAPI {
- parameter callback: (form) None (optional)
- returns: RequestBuilder<Void>
*/
open class func testEndpointParametersWithRequestBuilder(number: Double, double: Double, patternWithoutDelimiter: String, byte: Data, integer: Int? = nil, int32: Int? = nil, int64: Int64? = nil, float: Float? = nil, string: String? = nil, binary: URL? = nil, date: Date? = nil, dateTime: Date? = nil, password: String? = nil, callback: String? = nil) -> RequestBuilder<Void> {
open class func testEndpointParametersWithRequestBuilder(number: Double, double: Double, patternWithoutDelimiter: String, byte: Data, integer: Int? = nil, int32: Int? = nil, int64: Int64? = nil, float: Float? = nil, string: String? = nil, binary: URL? = nil, date: OpenAPIDateWithoutTime? = nil, dateTime: Date? = nil, password: String? = nil, callback: String? = nil) -> RequestBuilder<Void> {
let localVariablePath = "/fake"
let localVariableURLString = PetstoreClientAPI.basePath + localVariablePath
let localVariableFormParams: [String: Any?] = [

View File

@ -21,12 +21,12 @@ public struct FormatTest: Codable, JSONEncodable, Hashable {
public var string: String?
public var byte: Data
public var binary: URL?
public var date: Date
public var date: OpenAPIDateWithoutTime
public var dateTime: Date?
public var uuid: UUID?
public var password: String
public init(integer: Int? = nil, int32: Int? = nil, int64: Int64? = nil, number: Double, float: Float? = nil, double: Double? = nil, string: String? = nil, byte: Data, binary: URL? = nil, date: Date, dateTime: Date? = nil, uuid: UUID? = nil, password: String) {
public init(integer: Int? = nil, int32: Int? = nil, int64: Int64? = nil, number: Double, float: Float? = nil, double: Double? = nil, string: String? = nil, byte: Data, binary: URL? = nil, date: OpenAPIDateWithoutTime, dateTime: Date? = nil, uuid: UUID? = nil, password: String) {
self.integer = integer
self.int32 = int32
self.int64 = int64

View File

@ -0,0 +1,69 @@
// OpenAPIDateWithoutTime.swift
//
// Generated by openapi-generator
// https://openapi-generator.tech
//
import Foundation
/// Represents a date without time information (e.g. a birthday) for transmission from and to a REST API
///
/// This type is used as a representation for openapi specs `date` format which does not contain
/// time information as opposed to the `date-time` format. Although it internally uses `Date` for
/// (de-)serialization as well the generator needs to be able to distinguish between the two formats.
/// - note: As `Date` is agnostic to timezones (and calendars), timezone information is needed to be able to add
/// an appropriate padding in order to transform to GMT+0 which is the assumed timezone in ISO 8601.
/// When decoding, GMT+0 can be assumed (again: ISO8601) so there is no padding necessary and wrappedDate
/// can be used safely.
public struct OpenAPIDateWithoutTime: Codable, Hashable, Equatable {
public let wrappedDate: Date
public let timezone: TimeZone
public enum CodingKeys: CodingKey, CaseIterable {
case wrappedDate
case timezone
}
/// On decoding ISO8601 timezone is assumed
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
self.wrappedDate = try container.decode(Date.self)
self.timezone = OpenISO8601DateFormatter.withoutTime.timeZone
}
/// Convenience Initializer which is useful when dealing with optionals a lot like e.g. in API mappers
public init?(wrappedDate: Date?, timezone: TimeZone = .current) {
guard let wrappedDate = wrappedDate else {
return nil
}
self.init(wrappedDate: wrappedDate, timezone: timezone)
}
/// Designated Initializer for `OpenAPIDateWithoutTime`
///
/// Since usually `Date`s without time components - as e.g. birthdays - are created Calendar- and timezone-aware
// it is important to also provide a timezone so that the generator is able to normalize the supplied Date to ISO8601 (GMT+0)
public init(wrappedDate: Date, timezone: TimeZone) {
self.wrappedDate = wrappedDate
self.timezone = timezone
}
/// Only the wrappedDate is encoded normalized to GMT+0 with an offset derived from the supplied Timezone
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(OpenISO8601DateFormatter.withoutTime.string(from: normalizedWrappedDate()))
}
/// Normalizes the wrappedDate to GMT+0 according to the supplied timezone
fileprivate func normalizedWrappedDate() -> Date {
return wrappedDate.addingTimeInterval(
Double(timezone.secondsFromGMT(for: wrappedDate)))
}
}
extension OpenAPIDateWithoutTime: JSONEncodable {
func encodeToJSON() -> Any {
return OpenISO8601DateFormatter.withoutTime.string(from: self.normalizedWrappedDate())
}
}

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -364,7 +364,7 @@ No authorization required
# **testEndpointParameters**
```swift
open class func testEndpointParameters(number: Double, double: Double, patternWithoutDelimiter: String, byte: Data, integer: Int? = nil, int32: Int? = nil, int64: Int64? = nil, float: Float? = nil, string: String? = nil, binary: URL? = nil, date: Date? = nil, dateTime: Date? = nil, password: String? = nil, callback: String? = nil, completion: @escaping (_ data: Void?, _ error: Error?) -> Void)
open class func testEndpointParameters(number: Double, double: Double, patternWithoutDelimiter: String, byte: Data, integer: Int? = nil, int32: Int? = nil, int64: Int64? = nil, float: Float? = nil, string: String? = nil, binary: URL? = nil, date: OpenAPIDateWithoutTime? = nil, dateTime: Date? = nil, password: String? = nil, callback: String? = nil, completion: @escaping (_ data: Void?, _ error: Error?) -> Void)
```
Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
@ -386,7 +386,7 @@ let int64 = 987 // Int64 | None (optional)
let float = 987 // Float | None (optional)
let string = "string_example" // String | None (optional)
let binary = URL(string: "https://example.com")! // URL | None (optional)
let date = Date() // Date | None (optional)
let date = 987 // OpenAPIDateWithoutTime | None (optional)
let dateTime = Date() // Date | None (optional)
let password = "password_example" // String | None (optional)
let callback = "callback_example" // String | None (optional)
@ -418,7 +418,7 @@ Name | Type | Description | Notes
**float** | **Float** | None | [optional]
**string** | **String** | None | [optional]
**binary** | **URL** | None | [optional]
**date** | **Date** | None | [optional]
**date** | **OpenAPIDateWithoutTime** | None | [optional]
**dateTime** | **Date** | None | [optional]
**password** | **String** | None | [optional]
**callback** | **String** | None | [optional]

View File

@ -12,7 +12,7 @@ Name | Type | Description | Notes
**string** | **String** | | [optional]
**byte** | **Data** | |
**binary** | **URL** | | [optional]
**date** | **Date** | |
**date** | **OpenAPIDateWithoutTime** | |
**dateTime** | **Date** | | [optional]
**uuid** | **UUID** | | [optional]
**password** | **String** | |

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -18,6 +18,15 @@ internal class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ internal class OpenISO8601DateFormatter: DateFormatter {
override internal func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -61,6 +61,7 @@ Sources/PetstoreClient/Models/TypeHolderDefault.swift
Sources/PetstoreClient/Models/TypeHolderExample.swift
Sources/PetstoreClient/Models/User.swift
Sources/PetstoreClient/Models/XmlItem.swift
Sources/PetstoreClient/OpenISO8601DateFormatter.swift
docs/AdditionalPropertiesAnyType.md
docs/AdditionalPropertiesArray.md
docs/AdditionalPropertiesBoolean.md

View File

@ -0,0 +1,56 @@
//
// OpenISO8601DateFormatter.swift
//
// Generated by openapi-generator
// https://openapi-generator.tech
//
import Foundation
// https://stackoverflow.com/a/50281094/976628
public class OpenISO8601DateFormatter: DateFormatter {
static let withoutSeconds: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
timeZone = TimeZone(secondsFromGMT: 0)
dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
}
override init() {
super.init()
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}

View File

@ -18,6 +18,15 @@ public class OpenISO8601DateFormatter: DateFormatter {
return formatter
}()
static let withoutTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
private func setup() {
calendar = Calendar(identifier: .iso8601)
locale = Locale(identifier: "en_US_POSIX")
@ -38,7 +47,10 @@ public class OpenISO8601DateFormatter: DateFormatter {
override public func date(from string: String) -> Date? {
if let result = super.date(from: string) {
return result
} else if let result = OpenISO8601DateFormatter.withoutSeconds.date(from: string) {
return result
}
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
return OpenISO8601DateFormatter.withoutTime.date(from: string)
}
}