// 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 { 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 (key, value) in rawHeader { header[key as! String] = value as? String } self.init(statusCode: response.statusCode, header: header, body: body) } } public enum Decoded { 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 AnyObject)>() static func addDecoder(clazz: T.Type, decoder: @escaping ((AnyObject, AnyObject?) -> Decoded)) { let key = "\(T.self)" decoders[key] = { decoder($0, $1) as AnyObject } } static func decode(clazz: T.Type, discriminator: String, source: AnyObject) -> Decoded { let key = discriminator if let decoder = decoders[key], let value = decoder(source, nil) as? Decoded { return value } else { return .failure(.typeMismatch(expected: String(describing: clazz), actual: String(describing: source))) } } static func decode(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(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(clazz: T.Type, source: AnyObject?) -> Decoded { 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(clazz: T.Type, source: AnyObject, instance: AnyObject?) -> Decoded { initialize() if let value = source.int32Value as? T, source is NSNumber, T.self is Int32.Type { return .success(value) } if let value = source.int32Value as? T, source is NSNumber, 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) } let key = "\(T.self)" if let decoder = decoders[key], let value = decoder(source, instance) as? Decoded { 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(decoded: Decoded) -> Decoded { return .success(decoded.value) } static func decodeOptional(clazz: T.Type, source: AnyObject?) -> Decoded { 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(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(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(clazz: T, source: AnyObject) -> Decoded { 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.dateFormat = format return formatter } // Decoder for Date Decoders.addDecoder(clazz: Date.self) { (source: AnyObject, instance: AnyObject?) -> Decoded 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 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}}}] return Decoders.decode(clazz: [{{{classname}}}].self, source: source, instance: instance) } // 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? {{dataType}} { 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}} {{#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): instance.{{name}} = value case let .failure(error): return .failure(error) } {{/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): return .failure(error) {{#isEnum}}{{#isMapContainer}}*/ default: break //TODO: handle enum map scenario{{/isMapContainer}}{{/isEnum}} } {{/allVars}} {{/unwrapRequired}} return .success(result) } else { return .failure(.typeMismatch(expected: "{{classname}}", actual: "\(source)")) } {{/allVars.isEmpty}} {{/isEnum}} }{{/isArrayModel}}{{/model}} {{/models}} }() static fileprivate func initialize() { _ = Decoders.__once } }