Open gotev opened 5 years ago
hello @gotev , can you propose a PR? i can help you to get it merged
Hi @HugoMario before starting the PR I wanted to make sure the solution is ok and up to swagger codegen standards. Since Swift Date
type corresponds to swagger's date-time
, the mapping for date-time will remain unchanged. What needs to be done is a custom type to represent just the ISO 8601 Full Date, as described in RFC 3339 section 5.6. I gave a look at what was done for Swift 3, but since then many things had changed in Swift 4, so I made a new type from scratch. Here it is:
import Foundation
public struct YearMonthDay {
public let year: Int
public let month: Int
public let day: Int
}
extension YearMonthDay: Codable, Equatable, Hashable, Comparable {
public init(from date: Date = Date()) {
let calendar = Calendar(identifier: .iso8601)
year = calendar.component(.year, from: date)
month = calendar.component(.month, from: date)
day = calendar.component(.day, from: date)
}
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let rawDate = try container.decode(String.self)
let formatter = ISO8601DateFormatter()
formatter.formatOptions = .withFullDate
guard let date = formatter.date(from: rawDate)
else { throw DecodingError.dataCorruptedError(in: container,
debugDescription: "Cannot decode date string \(rawDate)") }
let dateComponents = Calendar(identifier: .iso8601).dateComponents([.year, .month, .day], from: date)
guard let year = dateComponents.year,
let month = dateComponents.month,
let day = dateComponents.day
else { throw DecodingError.dataCorruptedError(in: container,
debugDescription: "Cannot decode date string \(rawDate)") }
self.year = year
self.month = month
self.day = day
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
let rawDate = String(describing: self)
let formatter = ISO8601DateFormatter()
formatter.formatOptions = .withFullDate
guard formatter.date(from: rawDate) != nil
else { throw EncodingError.invalidValue(self, EncodingError.Context(codingPath: container.codingPath,
debugDescription: "Cannot encode \(self)")) }
try container.encode(rawDate)
}
public static func < (lhs: YearMonthDay, rhs: YearMonthDay) -> Bool {
if lhs.year < rhs.year {
return true
} else if lhs.year > rhs.year {
return false
} else {
if lhs.month < rhs.month {
return true
} else if lhs.month > rhs.month {
return false
} else {
return lhs.day < rhs.day
}
}
}
public func add(years: Int = 0, months: Int = 0, days: Int = 0) -> YearMonthDay? {
var dateComponents = DateComponents()
dateComponents.year = year + years
dateComponents.month = month + months
dateComponents.day = day + days
guard let date = Calendar(identifier: .iso8601).date(from: dateComponents)
else { return nil }
return YearMonthDay(from: date)
}
}
extension YearMonthDay: CustomStringConvertible {
public var description: String {
return [String(format: "%04d", year), String(format: "%02d", month), String(format: "%02d", day)].joined(separator: "-")
}
}
And if you want to try it in an Xcode Playground just copy and paste the above and this:
struct FakePayload : Codable {
let date: YearMonthDay
}
let encoder = JSONEncoder()
let testDate = YearMonthDay(year: 2019, month: 12, day: 20)
let data = try encoder.encode(FakePayload(date: testDate))
print(String(data: data, encoding: .utf8)!)
let decoder = JSONDecoder()
let decodedPayload = try decoder.decode(FakePayload.self, from: data)
print(decodedPayload.date.year)
print(decodedPayload.date.month)
print(decodedPayload.date.day)
The idea is to add this new type as it is to the Swift4Codegen Supporting Files and then change the mapping in Swift4Codegen, updating failing tests. If it's ok, I'll go forward with the PR, otherwise let me know 😉
Hi everybody, when using Swift4 Swagger Codegen, there's a problem in distinguishing
Date
andDateTime
types declared in swagger, which gets both converted toDate
: https://github.com/swagger-api/swagger-codegen-generators/blob/master/src/main/java/io/swagger/codegen/v3/generators/swift/Swift4Codegen.java#L80-L81This wasn't a problem in Swift 3, where the the two types were different: https://github.com/swagger-api/swagger-codegen-generators/blob/master/src/main/java/io/swagger/codegen/v3/generators/swift/Swift3Codegen.java#L38-L39
Has anyone had the same problem? Most of all, how should we address it and solve it?