mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-11-20 18:43:56 +00:00
* update versions of dependencies on swift4 and swift3 * change syntax for swift4 * run petstore script * change enum case from UpperCamel to lowerCamel * remove unneeded break statements * avoid wrapping conditionals in parentheses * avoid force casting * run pod update on petstore/swift4/rxswift * update project for swift 4 * run swift4-petstore-all.sh * fix compile error * avoid use iso8601 date strategy for encoder / decoder * resolve file references
403 lines
16 KiB
Plaintext
403 lines
16 KiB
Plaintext
// Models.swift
|
|
//
|
|
// Generated by swagger-codegen
|
|
// https://github.com/swagger-api/swagger-codegen
|
|
//
|
|
|
|
import Foundation
|
|
|
|
protocol JSONEncodable {
|
|
func encodeToJSON() -> Any
|
|
}
|
|
|
|
public enum ErrorResponse : Error {
|
|
case HttpError(statusCode: Int, data: Data?, error: Error)
|
|
case DecodeError(response: Data?, decodeError: DecodeError)
|
|
}
|
|
|
|
open class Response<T> {
|
|
open let statusCode: Int
|
|
open let header: [String: String]
|
|
open let body: T?
|
|
|
|
public init(statusCode: Int, header: [String: String], body: T?) {
|
|
self.statusCode = statusCode
|
|
self.header = header
|
|
self.body = body
|
|
}
|
|
|
|
public convenience init(response: HTTPURLResponse, body: T?) {
|
|
let rawHeader = response.allHeaderFields
|
|
var header = [String:String]()
|
|
for case let (key, value) as (String, String) in rawHeader {
|
|
header[key] = value
|
|
}
|
|
self.init(statusCode: response.statusCode, header: header, body: body)
|
|
}
|
|
}
|
|
|
|
public enum Decoded<ValueType> {
|
|
case success(ValueType)
|
|
case failure(DecodeError)
|
|
}
|
|
|
|
public extension Decoded {
|
|
var value: ValueType? {
|
|
switch self {
|
|
case let .success(value):
|
|
return value
|
|
case .failure:
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
public enum DecodeError {
|
|
case typeMismatch(expected: String, actual: String)
|
|
case missingKey(key: String)
|
|
case parseError(message: String)
|
|
}
|
|
|
|
private var once = Int()
|
|
class Decoders {
|
|
static fileprivate var decoders = Dictionary<String, ((AnyObject, AnyObject?) -> AnyObject)>()
|
|
|
|
static func addDecoder<T>(clazz: T.Type, decoder: @escaping ((AnyObject, AnyObject?) -> Decoded<T>)) {
|
|
let key = "\(T.self)"
|
|
decoders[key] = { decoder($0, $1) as AnyObject }
|
|
}
|
|
|
|
static func decode<T>(clazz: T.Type, discriminator: String, source: AnyObject) -> Decoded<T> {
|
|
let key = discriminator
|
|
if let decoder = decoders[key], let value = decoder(source, nil) as? Decoded<T> {
|
|
return value
|
|
} else {
|
|
return .failure(.typeMismatch(expected: String(describing: clazz), actual: String(describing: source)))
|
|
}
|
|
}
|
|
|
|
static func decode<T>(clazz: [T].Type, source: AnyObject) -> Decoded<[T]> {
|
|
if let sourceArray = source as? [AnyObject] {
|
|
var values = [T]()
|
|
for sourceValue in sourceArray {
|
|
switch Decoders.decode(clazz: T.self, source: sourceValue, instance: nil) {
|
|
case let .success(value):
|
|
values.append(value)
|
|
case let .failure(error):
|
|
return .failure(error)
|
|
}
|
|
}
|
|
return .success(values)
|
|
} else {
|
|
return .failure(.typeMismatch(expected: String(describing: clazz), actual: String(describing: source)))
|
|
}
|
|
}
|
|
|
|
static func decode<T>(clazz: T.Type, source: AnyObject) -> Decoded<T> {
|
|
switch Decoders.decode(clazz: T.self, source: source, instance: nil) {
|
|
case let .success(value):
|
|
return .success(value)
|
|
case let .failure(error):
|
|
return .failure(error)
|
|
}
|
|
}
|
|
|
|
static open func decode<T: RawRepresentable>(clazz: T.Type, source: AnyObject) -> Decoded<T> {
|
|
if let value = source as? T.RawValue {
|
|
if let enumValue = T.init(rawValue: value) {
|
|
return .success(enumValue)
|
|
} else {
|
|
return .failure(.typeMismatch(expected: "A value from the enumeration \(T.self)", actual: "\(value)"))
|
|
}
|
|
} else {
|
|
return .failure(.typeMismatch(expected: "\(T.RawValue.self) matching a case from the enumeration \(T.self)", actual: String(describing: type(of: source))))
|
|
}
|
|
}
|
|
|
|
static func decode<T, Key: Hashable>(clazz: [Key:T].Type, source: AnyObject) -> Decoded<[Key:T]> {
|
|
if let sourceDictionary = source as? [Key: AnyObject] {
|
|
var dictionary = [Key:T]()
|
|
for (key, value) in sourceDictionary {
|
|
switch Decoders.decode(clazz: T.self, source: value, instance: nil) {
|
|
case let .success(value):
|
|
dictionary[key] = value
|
|
case let .failure(error):
|
|
return .failure(error)
|
|
}
|
|
}
|
|
return .success(dictionary)
|
|
} else {
|
|
return .failure(.typeMismatch(expected: String(describing: clazz), actual: String(describing: source)))
|
|
}
|
|
}
|
|
|
|
static func decodeOptional<T: RawRepresentable>(clazz: T.Type, source: AnyObject?) -> Decoded<T?> {
|
|
guard !(source is NSNull), source != nil else { return .success(nil) }
|
|
if let value = source as? T.RawValue {
|
|
if let enumValue = T.init(rawValue: value) {
|
|
return .success(enumValue)
|
|
} else {
|
|
return .failure(.typeMismatch(expected: "A value from the enumeration \(T.self)", actual: "\(value)"))
|
|
}
|
|
} else {
|
|
return .failure(.typeMismatch(expected: "\(T.RawValue.self) matching a case from the enumeration \(T.self)", actual: String(describing: type(of: source))))
|
|
}
|
|
}
|
|
|
|
static func decode<T>(clazz: T.Type, source: AnyObject, instance: AnyObject?) -> Decoded<T> {
|
|
initialize()
|
|
if let sourceNumber = source as? NSNumber, let value = sourceNumber.int32Value as? T, T.self is Int32.Type {
|
|
return .success(value)
|
|
}
|
|
if let sourceNumber = source as? NSNumber, let value = sourceNumber.int32Value as? T, T.self is Int64.Type {
|
|
return .success(value)
|
|
}
|
|
if let intermediate = source as? String, let value = UUID(uuidString: intermediate) as? T, source is String, T.self is UUID.Type {
|
|
return .success(value)
|
|
}
|
|
if let value = source as? T {
|
|
return .success(value)
|
|
}
|
|
if let intermediate = source as? String, let value = Data(base64Encoded: intermediate) as? T {
|
|
return .success(value)
|
|
}
|
|
{{#lenientTypeCast}}
|
|
if T.self is Int32.Type && source is String {
|
|
return (source as! NSString).intValue as! T
|
|
}
|
|
if T.self is Int64.Type && source is String {
|
|
return (source as! NSString).intValue as! T
|
|
}
|
|
if T.self is Bool.Type && source is String {
|
|
return (source as! NSString).boolValue as! T
|
|
}
|
|
if T.self is String.Type && source is NSNumber {
|
|
return String(describing: source) as! T
|
|
}
|
|
{{/lenientTypeCast}}
|
|
|
|
let key = "\(T.self)"
|
|
if let decoder = decoders[key], let value = decoder(source, instance) as? Decoded<T> {
|
|
return value
|
|
} else {
|
|
return .failure(.typeMismatch(expected: String(describing: clazz), actual: String(describing: source)))
|
|
}
|
|
}
|
|
|
|
//Convert a Decoded so that its value is optional. DO WE STILL NEED THIS?
|
|
static func toOptional<T>(decoded: Decoded<T>) -> Decoded<T?> {
|
|
return .success(decoded.value)
|
|
}
|
|
|
|
static func decodeOptional<T>(clazz: T.Type, source: AnyObject?) -> Decoded<T?> {
|
|
if let source = source, !(source is NSNull) {
|
|
switch Decoders.decode(clazz: clazz, source: source, instance: nil) {
|
|
case let .success(value): return .success(value)
|
|
case let .failure(error): return .failure(error)
|
|
}
|
|
} else {
|
|
return .success(nil)
|
|
}
|
|
}
|
|
|
|
static func decodeOptional<T>(clazz: [T].Type, source: AnyObject?) -> Decoded<[T]?> where T: RawRepresentable {
|
|
if let source = source as? [AnyObject] {
|
|
var values = [T]()
|
|
for sourceValue in source {
|
|
switch Decoders.decodeOptional(clazz: T.self, source: sourceValue) {
|
|
case let .success(value): if let value = value { values.append(value) }
|
|
case let .failure(error): return .failure(error)
|
|
}
|
|
}
|
|
return .success(values)
|
|
} else {
|
|
return .success(nil)
|
|
}
|
|
}
|
|
|
|
static func decodeOptional<T>(clazz: [T].Type, source: AnyObject?) -> Decoded<[T]?> {
|
|
if let source = source as? [AnyObject] {
|
|
var values = [T]()
|
|
for sourceValue in source {
|
|
switch Decoders.decode(clazz: T.self, source: sourceValue, instance: nil) {
|
|
case let .success(value): values.append(value)
|
|
case let .failure(error): return .failure(error)
|
|
}
|
|
}
|
|
return .success(values)
|
|
} else {
|
|
return .success(nil)
|
|
}
|
|
}
|
|
|
|
static func decodeOptional<T, Key: Hashable>(clazz: [Key:T].Type, source: AnyObject?) -> Decoded<[Key:T]?> {
|
|
if let sourceDictionary = source as? [Key: AnyObject] {
|
|
var dictionary = [Key:T]()
|
|
for (key, value) in sourceDictionary {
|
|
switch Decoders.decode(clazz: T.self, source: value, instance: nil) {
|
|
case let .success(value): dictionary[key] = value
|
|
case let .failure(error): return .failure(error)
|
|
}
|
|
}
|
|
return .success(dictionary)
|
|
} else {
|
|
return .success(nil)
|
|
}
|
|
}
|
|
|
|
static func decodeOptional<T: RawRepresentable, U: AnyObject>(clazz: T, source: AnyObject) -> Decoded<T?> where T.RawValue == U {
|
|
if let value = source as? U {
|
|
if let enumValue = T.init(rawValue: value) {
|
|
return .success(enumValue)
|
|
} else {
|
|
return .failure(.typeMismatch(expected: "A value from the enumeration \(T.self)", actual: "\(value)"))
|
|
}
|
|
} else {
|
|
return .failure(.typeMismatch(expected: "String", actual: String(describing: type(of: source))))
|
|
}
|
|
}
|
|
|
|
|
|
private static var __once: () = {
|
|
let formatters = [
|
|
"yyyy-MM-dd",
|
|
"yyyy-MM-dd'T'HH:mm:ssZZZZZ",
|
|
"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ",
|
|
"yyyy-MM-dd'T'HH:mm:ss'Z'",
|
|
"yyyy-MM-dd'T'HH:mm:ss.SSS",
|
|
"yyyy-MM-dd HH:mm:ss"
|
|
].map { (format: String) -> DateFormatter in
|
|
let formatter = DateFormatter()
|
|
formatter.locale = Locale(identifier: "en_US_POSIX")
|
|
formatter.dateFormat = format
|
|
return formatter
|
|
}
|
|
// Decoder for Date
|
|
Decoders.addDecoder(clazz: Date.self) { (source: AnyObject, instance: AnyObject?) -> Decoded<Date> in
|
|
if let sourceString = source as? String {
|
|
for formatter in formatters {
|
|
if let date = formatter.date(from: sourceString) {
|
|
return .success(date)
|
|
}
|
|
}
|
|
}
|
|
if let sourceInt = source as? Int {
|
|
// treat as a java date
|
|
return .success(Date(timeIntervalSince1970: Double(sourceInt / 1000) ))
|
|
}
|
|
if source is String || source is Int {
|
|
return .failure(.parseError(message: "Could not decode date"))
|
|
} else {
|
|
return .failure(.typeMismatch(expected: "String or Int", actual: "\(source)"))
|
|
}
|
|
}
|
|
|
|
// Decoder for ISOFullDate
|
|
Decoders.addDecoder(clazz: ISOFullDate.self) { (source: AnyObject, instance: AnyObject?) -> Decoded<ISOFullDate> in
|
|
if let string = source as? String,
|
|
let isoDate = ISOFullDate.from(string: string) {
|
|
return .success(isoDate)
|
|
} else {
|
|
return .failure(.typeMismatch(expected: "ISO date", actual: "\(source)"))
|
|
}
|
|
}
|
|
|
|
{{#models}}
|
|
{{#model}}
|
|
{{^isArrayModel}}
|
|
// Decoder for [{{{classname}}}]
|
|
Decoders.addDecoder(clazz: [{{{classname}}}].self) { (source: AnyObject, instance: AnyObject?) -> Decoded<[{{{classname}}}]> in
|
|
return Decoders.decode(clazz: [{{{classname}}}].self, source: source)
|
|
}
|
|
|
|
// Decoder for {{{classname}}}
|
|
Decoders.addDecoder(clazz: {{{classname}}}.self) { (source: AnyObject, instance: AnyObject?) -> Decoded<{{{classname}}}> in
|
|
{{#isEnum}}
|
|
//TODO: I don't think we need this anymore
|
|
return Decoders.decode(clazz: {{{classname}}}.self, source: source, instance: instance)
|
|
{{/isEnum}}
|
|
{{^isEnum}}
|
|
{{#allVars.isEmpty}}
|
|
if let source = source as? {{classname}} {
|
|
return .success(source)
|
|
} else {
|
|
return .failure(.typeMismatch(expected: "Typealias {{classname}}", actual: "\(source)"))
|
|
}
|
|
{{/allVars.isEmpty}}
|
|
{{^allVars.isEmpty}}
|
|
if let sourceDictionary = source as? [AnyHashable: Any] {
|
|
{{#discriminator}}
|
|
// Check discriminator to support inheritance
|
|
if let discriminator = sourceDictionary["{{discriminator}}"] as? String, instance == nil && discriminator != "{{classname}}"{
|
|
return Decoders.decode(clazz: {{classname}}.self, discriminator: discriminator, source: source)
|
|
}
|
|
{{/discriminator}}
|
|
{{#additionalPropertiesType}}
|
|
var propsDictionary = sourceDictionary
|
|
let keys : [AnyHashable] = [{{#allVars}}{{^-last}}"{{baseName}}", {{/-last}}{{#-last}}"{{baseName}}"{{/-last}}{{/allVars}}]
|
|
{{/additionalPropertiesType}}
|
|
{{#unwrapRequired}}
|
|
{{#requiredVars}}
|
|
guard let {{name}}Source = sourceDictionary["{{baseName}}"] as AnyObject? else {
|
|
return .failure(.missingKey(key: "{{baseName}}"))
|
|
}
|
|
guard let {{name}} = Decoders.decode(clazz: {{#isEnum}}{{^isListContainer}}{{classname}}.{{enumName}}.self{{/isListContainer}}{{#isListContainer}}Array<{{classname}}.{{enumName}}>.self{{/isListContainer}}{{/isEnum}}{{^isEnum}}{{{datatype}}}.self{{/isEnum}}.self, source: {{name}}Source).value else {
|
|
return .failure(.typeMismatch(expected: "{{classname}}", actual: "\({{name}}Source)"))
|
|
}
|
|
{{/requiredVars}}
|
|
let _result = {{classname}}({{#requiredVars}}{{^-first}}, {{/-first}}{{name}}: {{name}}{{/requiredVars}})
|
|
{{#optionalVars}}
|
|
switch Decoders.decodeOptional(clazz: {{#isEnum}}{{^isListContainer}}{{classname}}.{{enumName}}.self{{/isListContainer}}{{#isListContainer}}Array<{{classname}}.{{enumName}}>.self{{/isListContainer}}{{/isEnum}}{{^isEnum}}{{{datatype}}}.self{{/isEnum}}, source: sourceDictionary["{{baseName}}"] as AnyObject?) {
|
|
case let .success(value): _result.{{name}} = value
|
|
case let .failure(error): break
|
|
}
|
|
{{/optionalVars}}
|
|
{{/unwrapRequired}}
|
|
{{^unwrapRequired}}
|
|
let _result = instance == nil ? {{classname}}() : instance as! {{classname}}
|
|
{{#parent}}
|
|
if decoders["\({{parent}}.self)"] != nil {
|
|
_ = Decoders.decode(clazz: {{parent}}.self, source: source, instance: _result)
|
|
}
|
|
{{/parent}}
|
|
{{#allVars}}
|
|
switch Decoders.decodeOptional(clazz: {{#isEnum}}{{^isListContainer}}{{classname}}.{{enumName}}.self{{/isListContainer}}{{#isListContainer}}Array<{{classname}}.{{enumName}}>.self{{/isListContainer}}{{/isEnum}}{{^isEnum}}{{{datatype}}}.self{{/isEnum}}, source: sourceDictionary["{{baseName}}"] as AnyObject?) {
|
|
{{#isEnum}}{{#isMapContainer}}/*{{/isMapContainer}}{{/isEnum}}
|
|
case let .success(value): _result.{{name}} = value
|
|
case let .failure(error): break
|
|
{{#isEnum}}{{#isMapContainer}}*/ default: break //TODO: handle enum map scenario{{/isMapContainer}}{{/isEnum}}
|
|
}
|
|
{{/allVars}}
|
|
{{/unwrapRequired}}
|
|
{{#additionalPropertiesType}}
|
|
|
|
for key in keys {
|
|
propsDictionary.removeValue(forKey: key)
|
|
}
|
|
|
|
for key in propsDictionary.keys {
|
|
switch Decoders.decodeOptional(clazz: String.self, source: propsDictionary[key] as AnyObject?) {
|
|
|
|
case let .success(value): _result[key] = value
|
|
default: continue
|
|
|
|
}
|
|
}
|
|
{{/additionalPropertiesType}}
|
|
return .success(_result)
|
|
} else {
|
|
return .failure(.typeMismatch(expected: "{{classname}}", actual: "\(source)"))
|
|
}
|
|
{{/allVars.isEmpty}}
|
|
{{/isEnum}}
|
|
}
|
|
{{/isArrayModel}}
|
|
{{/model}}
|
|
{{/models}}
|
|
}()
|
|
|
|
static fileprivate func initialize() {
|
|
_ = Decoders.__once
|
|
}
|
|
}
|