forked from loafle/openapi-generator-original
328 lines
13 KiB
Plaintext
328 lines
13 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 (key, value) in rawHeader {
|
|
header[key as! String] = value as? String
|
|
}
|
|
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, 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 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<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]?> {
|
|
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 where T.RawValue == U>(clazz: T, source: AnyObject) -> Decoded<T?> {
|
|
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<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}}}]
|
|
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
|
|
}
|
|
}
|