From cb4b13403ac845c083dca18fc70adfd202b7020d Mon Sep 17 00:00:00 2001 From: Joshua Sosso Date: Fri, 9 Aug 2024 21:38:14 -0500 Subject: [PATCH] further progress --- .../swift-codegen-reference/Package.resolved | 15 - .../swift-codegen-reference/Package.swift | 7 +- .../Sources/ArriJSON.swift | 1404 +++++++++++++++++ .../Sources/SwiftCodegenReference.swift | 326 +++- .../Tests/BookTests.swift | 8 +- .../Tests/NestedObjectTest.swift | 16 +- .../Tests/ObjectWithEveryTypeTest.swift | 8 +- .../swift-codegen-reference/project.json | 19 +- 8 files changed, 1679 insertions(+), 124 deletions(-) delete mode 100644 languages/swift/swift-codegen-reference/Package.resolved create mode 100644 languages/swift/swift-codegen-reference/Sources/ArriJSON.swift diff --git a/languages/swift/swift-codegen-reference/Package.resolved b/languages/swift/swift-codegen-reference/Package.resolved deleted file mode 100644 index cb83e648..00000000 --- a/languages/swift/swift-codegen-reference/Package.resolved +++ /dev/null @@ -1,15 +0,0 @@ -{ - "originHash" : "5a0a06358dc0a017c61f18bb89ae734794b03cdaa4212dd0b0f9c9e0331907ba", - "pins" : [ - { - "identity" : "objectmapper", - "kind" : "remoteSourceControl", - "location" : "https://github.com/tristanhimmelman/ObjectMapper.git", - "state" : { - "revision" : "6021c6035e83a306047348666f6400dc61445d3b", - "version" : "4.4.3" - } - } - ], - "version" : 3 -} diff --git a/languages/swift/swift-codegen-reference/Package.swift b/languages/swift/swift-codegen-reference/Package.swift index 0d4f59e7..2e2a9b4c 100644 --- a/languages/swift/swift-codegen-reference/Package.swift +++ b/languages/swift/swift-codegen-reference/Package.swift @@ -14,17 +14,12 @@ let package = Package( name: "SwiftCodegenReference", targets: ["SwiftCodegenReference"]), ], - dependencies: [ - .package(url: "https://github.com/tristanhimmelman/ObjectMapper.git", .upToNextMajor(from: "4.1.0")), - ], targets: [ // Targets are the basic building blocks of a package, defining a module or a test suite. // Targets can depend on other targets in this package and products from dependencies. .target( name: "SwiftCodegenReference", - dependencies: [ - "ObjectMapper" - ] + dependencies: [] ), .testTarget( name: "BookTests", diff --git a/languages/swift/swift-codegen-reference/Sources/ArriJSON.swift b/languages/swift/swift-codegen-reference/Sources/ArriJSON.swift new file mode 100644 index 00000000..a249a845 --- /dev/null +++ b/languages/swift/swift-codegen-reference/Sources/ArriJSON.swift @@ -0,0 +1,1404 @@ +// ArriJSON.swift +// +// Copyright (c) 2014 - 2017 Ruoyu Fu, Pinglin Tang +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +// MARK: - Error +// swiftlint:disable line_length +public enum ArriJSONError: Int, Swift.Error { + case unsupportedType = 999 + case indexOutOfBounds = 900 + case elementTooDeep = 902 + case wrongType = 901 + case notExist = 500 + case invalidJSON = 490 +} + +extension ArriJSONError: CustomNSError { + + /// return the error domain of ArriJSONError + public static var errorDomain: String { return "com.arrijson.ArriJSON" } + + /// return the error code of ArriJSONError + public var errorCode: Int { return self.rawValue } + + /// return the userInfo of ArriJSONError + public var errorUserInfo: [String: Any] { + switch self { + case .unsupportedType: + return [NSLocalizedDescriptionKey: "It is an unsupported type."] + case .indexOutOfBounds: + return [NSLocalizedDescriptionKey: "Array Index is out of bounds."] + case .wrongType: + return [NSLocalizedDescriptionKey: "Couldn't merge, because the JSONs differ in type on top level."] + case .notExist: + return [NSLocalizedDescriptionKey: "Dictionary key does not exist."] + case .invalidJSON: + return [NSLocalizedDescriptionKey: "JSON is invalid."] + case .elementTooDeep: + return [NSLocalizedDescriptionKey: "Element too deep. Increase maxObjectDepth and make sure there is no reference loop."] + } + } +} + +// MARK: - JSON Type + +/** +JSON's type definitions. + +See http://www.json.org +*/ +public enum Type: Int { + case number + case string + case bool + case array + case dictionary + case null + case unknown +} + +// MARK: - JSON Base + +public struct JSON { + + /** + Creates a JSON using the data. + + - parameter data: The NSData used to convert to json.Top level object in data is an NSArray or NSDictionary + - parameter opt: The JSON serialization reading options. `[]` by default. + + - returns: The created JSON + */ + public init(data: Data, options opt: JSONSerialization.ReadingOptions = []) throws { + let object: Any = try JSONSerialization.jsonObject(with: data, options: opt) + self.init(jsonObject: object) + } + + /** + Creates a JSON object + - note: this does not parse a `String` into JSON, instead use `init(parseJSON: String)` + + - parameter object: the object + + - returns: the created JSON object + */ + public init(_ object: Any) { + switch object { + case let object as Data: + do { + try self.init(data: object) + } catch { + self.init(jsonObject: NSNull()) + } + default: + self.init(jsonObject: object) + } + } + + /** + Parses the JSON string into a JSON object + + - parameter json: the JSON string + + - returns: the created JSON object + */ + public init(parseJSON jsonString: String) { + if let data = jsonString.data(using: .utf8) { + self.init(data) + } else { + self.init(NSNull()) + } + } + + /** + Creates a JSON using the object. + + - parameter jsonObject: The object must have the following properties: All objects are NSString/String, NSNumber/Int/Float/Double/Bool, NSArray/Array, NSDictionary/Dictionary, or NSNull; All dictionary keys are NSStrings/String; NSNumbers are not NaN or infinity. + + - returns: The created JSON + */ + fileprivate init(jsonObject: Any) { + object = jsonObject + } + + /** + Merges another JSON into this JSON, whereas primitive values which are not present in this JSON are getting added, + present values getting overwritten, array values getting appended and nested JSONs getting merged the same way. + + - parameter other: The JSON which gets merged into this JSON + + - throws `ErrorWrongType` if the other JSONs differs in type on the top level. + */ + public mutating func merge(with other: JSON) throws { + try self.merge(with: other, typecheck: true) + } + + /** + Merges another JSON into this JSON and returns a new JSON, whereas primitive values which are not present in this JSON are getting added, + present values getting overwritten, array values getting appended and nested JSONS getting merged the same way. + + - parameter other: The JSON which gets merged into this JSON + + - throws `ErrorWrongType` if the other JSONs differs in type on the top level. + + - returns: New merged JSON + */ + public func merged(with other: JSON) throws -> JSON { + var merged = self + try merged.merge(with: other, typecheck: true) + return merged + } + + /** + Private woker function which does the actual merging + Typecheck is set to true for the first recursion level to prevent total override of the source JSON + */ + fileprivate mutating func merge(with other: JSON, typecheck: Bool) throws { + if type == other.type { + switch type { + case .dictionary: + for (key, _) in other { + try self[key].merge(with: other[key], typecheck: false) + } + case .array: + self = JSON(arrayValue + other.arrayValue) + default: + self = other + } + } else { + if typecheck { + throw ArriJSONError.wrongType + } else { + self = other + } + } + } + + /// Private object + fileprivate var rawArray: [Any] = [] + fileprivate var rawDictionary: [String: Any] = [:] + fileprivate var rawString: String = "" + fileprivate var rawNumber: NSNumber = 0 + fileprivate var rawNull: NSNull = NSNull() + fileprivate var rawBool: Bool = false + + /// JSON type, fileprivate setter + public fileprivate(set) var type: Type = .null + + /// Error in JSON, fileprivate setter + public fileprivate(set) var error: ArriJSONError? + + /// Object in JSON + public var object: Any { + get { + switch type { + case .array: return rawArray + case .dictionary: return rawDictionary + case .string: return rawString + case .number: return rawNumber + case .bool: return rawBool + default: return rawNull + } + } + set { + error = nil + switch unwrap(newValue) { + case let number as NSNumber: + if number.isBool { + type = .bool + rawBool = number.boolValue + } else { + type = .number + rawNumber = number + } + case let string as String: + type = .string + rawString = string + case _ as NSNull: + type = .null + case Optional.none: + type = .null + case let array as [Any]: + type = .array + rawArray = array + case let dictionary as [String: Any]: + type = .dictionary + rawDictionary = dictionary + default: + type = .unknown + error = ArriJSONError.unsupportedType + } + } + } + + /// The static null JSON + @available(*, unavailable, renamed:"null") + public static var nullJSON: JSON { return null } + public static var null: JSON { return JSON(NSNull()) } +} + +/// Private method to unwarp an object recursively +private func unwrap(_ object: Any) -> Any { + switch object { + case let json as JSON: + return unwrap(json.object) + case let array as [Any]: + return array.map(unwrap) + case let dictionary as [String: Any]: + var d = dictionary + dictionary.forEach { pair in + d[pair.key] = unwrap(pair.value) + } + return d + default: + return object + } +} + +public enum Index: Comparable { + case array(Int) + case dictionary(DictionaryIndex) + case null + + static public func == (lhs: Index, rhs: Index) -> Bool { + switch (lhs, rhs) { + case (.array(let left), .array(let right)): return left == right + case (.dictionary(let left), .dictionary(let right)): return left == right + case (.null, .null): return true + default: return false + } + } + + static public func < (lhs: Index, rhs: Index) -> Bool { + switch (lhs, rhs) { + case (.array(let left), .array(let right)): return left < right + case (.dictionary(let left), .dictionary(let right)): return left < right + default: return false + } + } +} + +public typealias JSONIndex = Index +public typealias JSONRawIndex = Index + +extension JSON: Swift.Collection { + + public typealias Index = JSONRawIndex + + public var startIndex: Index { + switch type { + case .array: return .array(rawArray.startIndex) + case .dictionary: return .dictionary(rawDictionary.startIndex) + default: return .null + } + } + + public var endIndex: Index { + switch type { + case .array: return .array(rawArray.endIndex) + case .dictionary: return .dictionary(rawDictionary.endIndex) + default: return .null + } + } + + public func index(after i: Index) -> Index { + switch i { + case .array(let idx): return .array(rawArray.index(after: idx)) + case .dictionary(let idx): return .dictionary(rawDictionary.index(after: idx)) + default: return .null + } + } + + public subscript (position: Index) -> (String, JSON) { + switch position { + case .array(let idx): return (String(idx), JSON(rawArray[idx])) + case .dictionary(let idx): return (rawDictionary[idx].key, JSON(rawDictionary[idx].value)) + default: return ("", JSON.null) + } + } +} + +// MARK: - Subscript + +/** + * To mark both String and Int can be used in subscript. + */ +public enum JSONKey { + case index(Int) + case key(String) +} + +public protocol JSONSubscriptType { + var jsonKey: JSONKey { get } +} + +extension Int: JSONSubscriptType { + public var jsonKey: JSONKey { + return JSONKey.index(self) + } +} + +extension String: JSONSubscriptType { + public var jsonKey: JSONKey { + return JSONKey.key(self) + } +} + +extension JSON { + + /// If `type` is `.array`, return json whose object is `array[index]`, otherwise return null json with error. + fileprivate subscript(index index: Int) -> JSON { + get { + if type != .array { + var r = JSON.null + r.error = self.error ?? ArriJSONError.wrongType + return r + } else if rawArray.indices.contains(index) { + return JSON(rawArray[index]) + } else { + var r = JSON.null + r.error = ArriJSONError.indexOutOfBounds + return r + } + } + set { + if type == .array && + rawArray.indices.contains(index) && + newValue.error == nil { + rawArray[index] = newValue.object + } + } + } + + /// If `type` is `.dictionary`, return json whose object is `dictionary[key]` , otherwise return null json with error. + fileprivate subscript(key key: String) -> JSON { + get { + var r = JSON.null + if type == .dictionary { + if let o = rawDictionary[key] { + r = JSON(o) + } else { + r.error = ArriJSONError.notExist + } + } else { + r.error = self.error ?? ArriJSONError.wrongType + } + return r + } + set { + if type == .dictionary && newValue.error == nil { + rawDictionary[key] = newValue.object + } + } + } + + /// If `sub` is `Int`, return `subscript(index:)`; If `sub` is `String`, return `subscript(key:)`. + fileprivate subscript(sub sub: JSONSubscriptType) -> JSON { + get { + switch sub.jsonKey { + case .index(let index): return self[index: index] + case .key(let key): return self[key: key] + } + } + set { + switch sub.jsonKey { + case .index(let index): self[index: index] = newValue + case .key(let key): self[key: key] = newValue + } + } + } + + /** + Find a json in the complex data structures by using array of Int and/or String as path. + + Example: + + ``` + let json = JSON[data] + let path = [9,"list","person","name"] + let name = json[path] + ``` + + The same as: let name = json[9]["list"]["person"]["name"] + + - parameter path: The target json's path. + + - returns: Return a json found by the path or a null json with error + */ + public subscript(path: [JSONSubscriptType]) -> JSON { + get { + return path.reduce(self) { $0[sub: $1] } + } + set { + switch path.count { + case 0: return + case 1: self[sub:path[0]].object = newValue.object + default: + var aPath = path + aPath.remove(at: 0) + var nextJSON = self[sub: path[0]] + nextJSON[aPath] = newValue + self[sub: path[0]] = nextJSON + } + } + } + + /** + Find a json in the complex data structures by using array of Int and/or String as path. + + - parameter path: The target json's path. Example: + + let name = json[9,"list","person","name"] + + The same as: let name = json[9]["list"]["person"]["name"] + + - returns: Return a json found by the path or a null json with error + */ + public subscript(path: JSONSubscriptType...) -> JSON { + get { + return self[path] + } + set { + self[path] = newValue + } + } +} + +// MARK: - LiteralConvertible + +extension JSON: Swift.ExpressibleByStringLiteral { + + public init(stringLiteral value: StringLiteralType) { + self.init(value) + } + + public init(extendedGraphemeClusterLiteral value: StringLiteralType) { + self.init(value) + } + + public init(unicodeScalarLiteral value: StringLiteralType) { + self.init(value) + } +} + +extension JSON: Swift.ExpressibleByIntegerLiteral { + + public init(integerLiteral value: IntegerLiteralType) { + self.init(value) + } +} + +extension JSON: Swift.ExpressibleByBooleanLiteral { + + public init(booleanLiteral value: BooleanLiteralType) { + self.init(value) + } +} + +extension JSON: Swift.ExpressibleByFloatLiteral { + + public init(floatLiteral value: FloatLiteralType) { + self.init(value) + } +} + +extension JSON: Swift.ExpressibleByDictionaryLiteral { + public init(dictionaryLiteral elements: (String, Any)...) { + let dictionary = elements.reduce(into: [String: Any](), { $0[$1.0] = $1.1}) + self.init(dictionary) + } +} + +extension JSON: Swift.ExpressibleByArrayLiteral { + + public init(arrayLiteral elements: Any...) { + self.init(elements) + } +} + +// MARK: - Raw + +extension JSON: Swift.RawRepresentable { + + public init?(rawValue: Any) { + if JSON(rawValue).type == .unknown { + return nil + } else { + self.init(rawValue) + } + } + + public var rawValue: Any { + return object + } + + public func rawData(options opt: JSONSerialization.WritingOptions = JSONSerialization.WritingOptions(rawValue: 0)) throws -> Data { + guard JSONSerialization.isValidJSONObject(object) else { + throw ArriJSONError.invalidJSON + } + + return try JSONSerialization.data(withJSONObject: object, options: opt) + } + + public func rawString(_ encoding: String.Encoding = .utf8, options opt: JSONSerialization.WritingOptions = .prettyPrinted) -> String? { + do { + return try _rawString(encoding, options: [.jsonSerialization: opt]) + } catch { + print("Could not serialize object to JSON because:", error.localizedDescription) + return nil + } + } + + public func rawString(_ options: [writingOptionsKeys: Any]) -> String? { + let encoding = options[.encoding] as? String.Encoding ?? String.Encoding.utf8 + let maxObjectDepth = options[.maxObjextDepth] as? Int ?? 10 + do { + return try _rawString(encoding, options: options, maxObjectDepth: maxObjectDepth) + } catch { + print("Could not serialize object to JSON because:", error.localizedDescription) + return nil + } + } + + fileprivate func _rawString(_ encoding: String.Encoding = .utf8, options: [writingOptionsKeys: Any], maxObjectDepth: Int = 10) throws -> String? { + guard maxObjectDepth > 0 else { throw ArriJSONError.invalidJSON } + switch type { + case .dictionary: + do { + if !(options[.castNilToNSNull] as? Bool ?? false) { + let jsonOption = options[.jsonSerialization] as? JSONSerialization.WritingOptions ?? JSONSerialization.WritingOptions.prettyPrinted + let data = try rawData(options: jsonOption) + return String(data: data, encoding: encoding) + } + + guard let dict = object as? [String: Any?] else { + return nil + } + let body = try dict.keys.map { key throws -> String in + guard let value = dict[key] else { + return "\"\(key)\": null" + } + guard let unwrappedValue = value else { + return "\"\(key)\": null" + } + + let nestedValue = JSON(unwrappedValue) + guard let nestedString = try nestedValue._rawString(encoding, options: options, maxObjectDepth: maxObjectDepth - 1) else { + throw ArriJSONError.elementTooDeep + } + if nestedValue.type == .string { + return "\"\(key)\": \"\(nestedString.replacingOccurrences(of: "\\", with: "\\\\").replacingOccurrences(of: "\"", with: "\\\""))\"" + } else { + return "\"\(key)\": \(nestedString)" + } + } + + return "{\(body.joined(separator: ","))}" + } catch _ { + return nil + } + case .array: + do { + if !(options[.castNilToNSNull] as? Bool ?? false) { + let jsonOption = options[.jsonSerialization] as? JSONSerialization.WritingOptions ?? JSONSerialization.WritingOptions.prettyPrinted + let data = try rawData(options: jsonOption) + return String(data: data, encoding: encoding) + } + + guard let array = object as? [Any?] else { + return nil + } + let body = try array.map { value throws -> String in + guard let unwrappedValue = value else { + return "null" + } + + let nestedValue = JSON(unwrappedValue) + guard let nestedString = try nestedValue._rawString(encoding, options: options, maxObjectDepth: maxObjectDepth - 1) else { + throw ArriJSONError.invalidJSON + } + if nestedValue.type == .string { + return "\"\(nestedString.replacingOccurrences(of: "\\", with: "\\\\").replacingOccurrences(of: "\"", with: "\\\""))\"" + } else { + return nestedString + } + } + + return "[\(body.joined(separator: ","))]" + } catch _ { + return nil + } + case .string: return rawString + case .number: return rawNumber.stringValue + case .bool: return rawBool.description + case .null: return "null" + default: return nil + } + } +} + +// MARK: - Printable, DebugPrintable + +extension JSON: Swift.CustomStringConvertible, Swift.CustomDebugStringConvertible { + + public var description: String { + return rawString(options: .prettyPrinted) ?? "unknown" + } + + public var debugDescription: String { + return description + } +} + +// MARK: - Array + +extension JSON { + + //Optional [JSON] + public var array: [JSON]? { + return type == .array ? rawArray.map { JSON($0) } : nil + } + + //Non-optional [JSON] + public var arrayValue: [JSON] { + return self.array ?? [] + } + + //Optional [Any] + public var arrayObject: [Any]? { + get { + switch type { + case .array: return rawArray + default: return nil + } + } + set { + self.object = newValue ?? NSNull() + } + } +} + +// MARK: - Dictionary + +extension JSON { + + //Optional [String : JSON] + public var dictionary: [String: JSON]? { + if type == .dictionary { + var d = [String: JSON](minimumCapacity: rawDictionary.count) + rawDictionary.forEach { pair in + d[pair.key] = JSON(pair.value) + } + return d + } else { + return nil + } + } + + //Non-optional [String : JSON] + public var dictionaryValue: [String: JSON] { + return dictionary ?? [:] + } + + //Optional [String : Any] + + public var dictionaryObject: [String: Any]? { + get { + switch type { + case .dictionary: return rawDictionary + default: return nil + } + } + set { + object = newValue ?? NSNull() + } + } +} + +// MARK: - Bool + +extension JSON { // : Swift.Bool + + //Optional bool + public var bool: Bool? { + get { + switch type { + case .bool: return rawBool + default: return nil + } + } + set { + object = newValue ?? NSNull() + } + } + + //Non-optional bool + public var boolValue: Bool { + get { + switch type { + case .bool: return rawBool + case .number: return rawNumber.boolValue + case .string: return ["true", "y", "t", "yes", "1"].contains { rawString.caseInsensitiveCompare($0) == .orderedSame } + default: return false + } + } + set { + object = newValue + } + } +} + +// MARK: - String + +extension JSON { + + //Optional string + public var string: String? { + get { + switch type { + case .string: return object as? String + default: return nil + } + } + set { + object = newValue ?? NSNull() + } + } + + //Non-optional string + public var stringValue: String { + get { + switch type { + case .string: return object as? String ?? "" + case .number: return rawNumber.stringValue + case .bool: return (object as? Bool).map { String($0) } ?? "" + default: return "" + } + } + set { + object = newValue + } + } +} + +// MARK: - Number + +extension JSON { + + //Optional number + public var number: NSNumber? { + get { + switch type { + case .number: return rawNumber + case .bool: return NSNumber(value: rawBool ? 1 : 0) + default: return nil + } + } + set { + object = newValue ?? NSNull() + } + } + + //Non-optional number + public var numberValue: NSNumber { + get { + switch type { + case .string: + let decimal = NSDecimalNumber(string: object as? String) + return decimal == .notANumber ? .zero : decimal + case .number: return object as? NSNumber ?? NSNumber(value: 0) + case .bool: return NSNumber(value: rawBool ? 1 : 0) + default: return NSNumber(value: 0.0) + } + } + set { + object = newValue + } + } +} + +// MARK: - Null + +extension JSON { + + public var null: NSNull? { + set { + object = NSNull() + } + get { + switch type { + case .null: return rawNull + default: return nil + } + } + } + public func exists() -> Bool { + if let errorValue = error, (400...1000).contains(errorValue.errorCode) { + return false + } + return true + } +} + +// MARK: - URL + +extension JSON { + + //Optional URL + public var url: URL? { + get { + switch type { + case .string: + // Check for existing percent escapes first to prevent double-escaping of % character + if rawString.range(of: "%[0-9A-Fa-f]{2}", options: .regularExpression, range: nil, locale: nil) != nil { + return Foundation.URL(string: rawString) + } else if let encodedString_ = rawString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) { + // We have to use `Foundation.URL` otherwise it conflicts with the variable name. + return Foundation.URL(string: encodedString_) + } else { + return nil + } + default: + return nil + } + } + set { + object = newValue?.absoluteString ?? NSNull() + } + } +} + +// MARK: - Int, Double, Float, Int8, Int16, Int32, Int64 + +extension JSON { + + public var double: Double? { + get { + return number?.doubleValue + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var doubleValue: Double { + get { + return numberValue.doubleValue + } + set { + object = NSNumber(value: newValue) + } + } + + public var float: Float? { + get { + return number?.floatValue + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var floatValue: Float { + get { + return numberValue.floatValue + } + set { + object = NSNumber(value: newValue) + } + } + + public var int: Int? { + get { + return number?.intValue + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var intValue: Int { + get { + return numberValue.intValue + } + set { + object = NSNumber(value: newValue) + } + } + + public var uInt: UInt? { + get { + return number?.uintValue + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var uIntValue: UInt { + get { + return numberValue.uintValue + } + set { + object = NSNumber(value: newValue) + } + } + + public var int8: Int8? { + get { + return number?.int8Value + } + set { + if let newValue = newValue { + object = NSNumber(value: Int(newValue)) + } else { + object = NSNull() + } + } + } + + public var int8Value: Int8 { + get { + return numberValue.int8Value + } + set { + object = NSNumber(value: Int(newValue)) + } + } + + public var uInt8: UInt8? { + get { + return number?.uint8Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var uInt8Value: UInt8 { + get { + return numberValue.uint8Value + } + set { + object = NSNumber(value: newValue) + } + } + + public var int16: Int16? { + get { + return number?.int16Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var int16Value: Int16 { + get { + return numberValue.int16Value + } + set { + object = NSNumber(value: newValue) + } + } + + public var uInt16: UInt16? { + get { + return number?.uint16Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var uInt16Value: UInt16 { + get { + return numberValue.uint16Value + } + set { + object = NSNumber(value: newValue) + } + } + + public var int32: Int32? { + get { + return number?.int32Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var int32Value: Int32 { + get { + return numberValue.int32Value + } + set { + object = NSNumber(value: newValue) + } + } + + public var uInt32: UInt32? { + get { + return number?.uint32Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var uInt32Value: UInt32 { + get { + return numberValue.uint32Value + } + set { + object = NSNumber(value: newValue) + } + } + + public var int64: Int64? { + get { + return number?.int64Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var int64Value: Int64 { + get { + return numberValue.int64Value + } + set { + object = NSNumber(value: newValue) + } + } + + public var uInt64: UInt64? { + get { + return number?.uint64Value + } + set { + if let newValue = newValue { + object = NSNumber(value: newValue) + } else { + object = NSNull() + } + } + } + + public var uInt64Value: UInt64 { + get { + return numberValue.uint64Value + } + set { + object = NSNumber(value: newValue) + } + } +} + +// MARK: - Comparable + +extension JSON: Swift.Comparable {} + +public func == (lhs: JSON, rhs: JSON) -> Bool { + + switch (lhs.type, rhs.type) { + case (.number, .number): return lhs.rawNumber == rhs.rawNumber + case (.string, .string): return lhs.rawString == rhs.rawString + case (.bool, .bool): return lhs.rawBool == rhs.rawBool + case (.array, .array): return lhs.rawArray as NSArray == rhs.rawArray as NSArray + case (.dictionary, .dictionary): return lhs.rawDictionary as NSDictionary == rhs.rawDictionary as NSDictionary + case (.null, .null): return true + default: return false + } +} + +public func <= (lhs: JSON, rhs: JSON) -> Bool { + + switch (lhs.type, rhs.type) { + case (.number, .number): return lhs.rawNumber <= rhs.rawNumber + case (.string, .string): return lhs.rawString <= rhs.rawString + case (.bool, .bool): return lhs.rawBool == rhs.rawBool + case (.array, .array): return lhs.rawArray as NSArray == rhs.rawArray as NSArray + case (.dictionary, .dictionary): return lhs.rawDictionary as NSDictionary == rhs.rawDictionary as NSDictionary + case (.null, .null): return true + default: return false + } +} + +public func >= (lhs: JSON, rhs: JSON) -> Bool { + + switch (lhs.type, rhs.type) { + case (.number, .number): return lhs.rawNumber >= rhs.rawNumber + case (.string, .string): return lhs.rawString >= rhs.rawString + case (.bool, .bool): return lhs.rawBool == rhs.rawBool + case (.array, .array): return lhs.rawArray as NSArray == rhs.rawArray as NSArray + case (.dictionary, .dictionary): return lhs.rawDictionary as NSDictionary == rhs.rawDictionary as NSDictionary + case (.null, .null): return true + default: return false + } +} + +public func > (lhs: JSON, rhs: JSON) -> Bool { + + switch (lhs.type, rhs.type) { + case (.number, .number): return (lhs.rawNumber as NSNumber) > (rhs.rawNumber as NSNumber) + case (.string, .string): return lhs.rawString > rhs.rawString + default: return false + } +} + + +public func < (lhs: JSON, rhs: JSON) -> Bool { + + switch (lhs.type, rhs.type) { + case (.number, .number): return (lhs.rawNumber as NSNumber) < (rhs.rawNumber as NSNumber) + case (.string, .string): return lhs.rawString < rhs.rawString + default: return false + } +} + +private let trueNumber = NSNumber(value: true) +private let falseNumber = NSNumber(value: false) +private let trueObjCType = String(cString: trueNumber.objCType) +private let falseObjCType = String(cString: falseNumber.objCType) + +// MARK: - NSNumber: Comparable + +extension NSNumber { + fileprivate var isBool: Bool { + let objCType = String(cString: self.objCType) + if (self.compare(trueNumber) == .orderedSame && objCType == trueObjCType) || (self.compare(falseNumber) == .orderedSame && objCType == falseObjCType) { + return true + } else { + return false + } + } +} + +// #if !os(Linux) +func == (lhs: NSNumber, rhs: NSNumber) -> Bool { + switch (lhs.isBool, rhs.isBool) { + case (false, true): return false + case (true, false): return false + default: return lhs.compare(rhs) == .orderedSame + } +} +// #endif + +func != (lhs: NSNumber, rhs: NSNumber) -> Bool { + return !(lhs == rhs) +} + +func < (lhs: NSNumber, rhs: NSNumber) -> Bool { + + switch (lhs.isBool, rhs.isBool) { + case (false, true): return false + case (true, false): return false + default: return lhs.compare(rhs) == .orderedAscending + } +} + +func > (lhs: NSNumber, rhs: NSNumber) -> Bool { + + switch (lhs.isBool, rhs.isBool) { + case (false, true): return false + case (true, false): return false + default: return lhs.compare(rhs) == ComparisonResult.orderedDescending + } +} + +func <= (lhs: NSNumber, rhs: NSNumber) -> Bool { + + switch (lhs.isBool, rhs.isBool) { + case (false, true): return false + case (true, false): return false + default: return lhs.compare(rhs) != .orderedDescending + } +} + +func >= (lhs: NSNumber, rhs: NSNumber) -> Bool { + + switch (lhs.isBool, rhs.isBool) { + case (false, true): return false + case (true, false): return false + default: return lhs.compare(rhs) != .orderedAscending + } +} + +public enum writingOptionsKeys { + case jsonSerialization + case castNilToNSNull + case maxObjextDepth + case encoding +} + +// MARK: - JSON: Codable +extension JSON: Codable { + private static var codableTypes: [Codable.Type] { + return [ + Bool.self, + Int.self, + Int8.self, + Int16.self, + Int32.self, + Int64.self, + UInt.self, + UInt8.self, + UInt16.self, + UInt32.self, + UInt64.self, + Double.self, + String.self, + [JSON].self, + [String: JSON].self + ] + } + public init(from decoder: Decoder) throws { + var object: Any? + + if let container = try? decoder.singleValueContainer(), !container.decodeNil() { + for type in JSON.codableTypes { + if object != nil { + break + } + // try to decode value + switch type { + case let boolType as Bool.Type: + object = try? container.decode(boolType) + case let intType as Int.Type: + object = try? container.decode(intType) + case let int8Type as Int8.Type: + object = try? container.decode(int8Type) + case let int32Type as Int32.Type: + object = try? container.decode(int32Type) + case let int64Type as Int64.Type: + object = try? container.decode(int64Type) + case let uintType as UInt.Type: + object = try? container.decode(uintType) + case let uint8Type as UInt8.Type: + object = try? container.decode(uint8Type) + case let uint16Type as UInt16.Type: + object = try? container.decode(uint16Type) + case let uint32Type as UInt32.Type: + object = try? container.decode(uint32Type) + case let uint64Type as UInt64.Type: + object = try? container.decode(uint64Type) + case let doubleType as Double.Type: + object = try? container.decode(doubleType) + case let stringType as String.Type: + object = try? container.decode(stringType) + case let jsonValueArrayType as [JSON].Type: + object = try? container.decode(jsonValueArrayType) + case let jsonValueDictType as [String: JSON].Type: + object = try? container.decode(jsonValueDictType) + default: + break + } + } + } + self.init(object ?? NSNull()) + } + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + if object is NSNull { + try container.encodeNil() + return + } + switch object { + case let intValue as Int: + try container.encode(intValue) + case let int8Value as Int8: + try container.encode(int8Value) + case let int32Value as Int32: + try container.encode(int32Value) + case let int64Value as Int64: + try container.encode(int64Value) + case let uintValue as UInt: + try container.encode(uintValue) + case let uint8Value as UInt8: + try container.encode(uint8Value) + case let uint16Value as UInt16: + try container.encode(uint16Value) + case let uint32Value as UInt32: + try container.encode(uint32Value) + case let uint64Value as UInt64: + try container.encode(uint64Value) + case let doubleValue as Double: + try container.encode(doubleValue) + case let boolValue as Bool: + try container.encode(boolValue) + case let stringValue as String: + try container.encode(stringValue) + case is [Any]: + let jsonValueArray = array ?? [] + try container.encode(jsonValueArray) + case is [String: Any]: + let jsonValueDictValue = dictionary ?? [:] + try container.encode(jsonValueDictValue) + default: + break + } + } +} \ No newline at end of file diff --git a/languages/swift/swift-codegen-reference/Sources/SwiftCodegenReference.swift b/languages/swift/swift-codegen-reference/Sources/SwiftCodegenReference.swift index d4c0903e..cea666a9 100644 --- a/languages/swift/swift-codegen-reference/Sources/SwiftCodegenReference.swift +++ b/languages/swift/swift-codegen-reference/Sources/SwiftCodegenReference.swift @@ -1,12 +1,36 @@ import Foundation -import ObjectMapper -public protocol ExampleClientModel: Mappable, Equatable { +let jsonEncoder = JSONEncoder() + +func serializeString(input: String) -> String { + do { + let inputValue = try jsonEncoder.encode(input) + return String(data: inputValue, encoding: .utf8) ?? "\"\"" + } catch { + return "\"\"" + } +} + +func serializeAny(input: JSON) -> String { + do { + let inputValue = try jsonEncoder.encode(input) + return String(data: inputValue, encoding: .utf8) ?? "null" + } catch { + return "null" + } +} + +public protocol ExampleClientModel: Equatable { + init() + init(json: JSON) + init(JSONString: String) + func toJSONString() -> String func toQueryString() -> String } public protocol ExampleClientEnum: Equatable { - func toJsonString() -> String - func toQueryString() -> String + init() + init(serialValue: String) + func serialValue() -> String } public class ExampleClientDateFormatter { public let RFC3339DateFormatter: DateFormatter @@ -25,17 +49,6 @@ public class ExampleClientDateFormatter { } private let __dateFormatter = ExampleClientDateFormatter() -private let __dateTransformer = TransformOf( - fromJSON: { - if($0 == nil) { - return Date.now - } - return __dateFormatter.date(from: $0!) - }, - toJSON: { - return __dateFormatter.string(from: $0 ?? Date.now) - } -) public struct Book: ExampleClientModel, Equatable { public var id: String = "" @@ -55,15 +68,29 @@ public struct Book: ExampleClientModel, Equatable { self.updatedAt = updatedAt } public init() {} - public init?(map: Map) {} - - public mutating func mapping(map: Map) { - self.id <- map["id"] - self.name <- map["name"] - self.createdAt <- (map["createdAt"], __dateTransformer) - self.updatedAt <- (map["updatedAt"], __dateTransformer) + public init(json: JSON) { + self.id = json["name"].string ?? "" + self.name = json["name"].string ?? "" + self.createdAt = __dateFormatter.date(from: json["createdAt"].string ?? "") ?? Date.now + self.updatedAt = __dateFormatter.date(from: json["updatedAt"].string ?? "") ?? Date.now + } + public init(JSONString: String) { + self.init(json: JSON(stringLiteral: JSONString)) } + public func toJSONString() -> String{ + var __json = "{" + __json += "\"id\":" + __json += serializeString(input: self.id) + __json += ",\"name\":" + __json += serializeString(input: self.name) + __json += ",\"createdAt\":" + __json += "\"\(__dateFormatter.string(from: self.createdAt))\"" + __json += ",\"updatedAt\":" + __json += "\"\(__dateFormatter.string(from: self.updatedAt))\"" + __json += "}" + return __json + } public func toQueryString() -> String { var __queryParts: [String] = [] __queryParts.append("id=\(self.id)") @@ -74,8 +101,6 @@ public struct Book: ExampleClientModel, Equatable { } } - - public struct BookParams: ExampleClientModel { public var bookId: String = "" @@ -85,9 +110,18 @@ public struct BookParams: ExampleClientModel { self.bookId = bookId } public init() {} - public init?(map: ObjectMapper.Map) {} - public mutating func mapping(map: Map) { - self.bookId <- map["bookId"] + public init(json: JSON) { + self.bookId = json["bookId"].string ?? "" + } + public init(JSONString: String) { + self.init(json: JSON(stringLiteral: JSONString)) + } + public func toJSONString() -> String { + var __json = "{" + __json += "\"bookId\":" + __json += serializeString(input: self.bookId) + __json += "}" + return __json } public func toQueryString() -> String { var __queryParts: [String] = [] @@ -107,17 +141,23 @@ public struct NestedObject: ExampleClientModel { self.content = content } public init() {} - public init?(map: Map) {} - public mutating func mapping(map: Map) { - self.id <- map["id"] - self.content <- map["content"] + public init(json: JSON) { + self.id = json["id"].string ?? "" + self.content = json["content"].string ?? "" + } + public init(JSONString: String) { + self.init(json: JSON(stringLiteral: JSONString)) + } + public func toJSONString() -> String { + var __json = "{" + __json += "}" + return __json } public func toQueryString() -> String { var __queryParts: [String] = [] __queryParts.append("id=\(self.id)") __queryParts.append("content=\(self.content)") return __queryParts.joined(separator: "&") - } } @@ -140,7 +180,7 @@ public struct ObjectWithEveryType: ExampleClientModel { public var array: [Bool] = [] public var record: Dictionary = Dictionary() public var discriminator: Discriminator = Discriminator.a(DiscriminatorA()) - public var any: Any? = nil + public var any: JSON = JSON() public init( string: String, @@ -161,7 +201,7 @@ public struct ObjectWithEveryType: ExampleClientModel { array: [Bool], record: Dictionary, discriminator: Discriminator, - any: Any? + any: JSON ) { self.string = string self.boolean = boolean @@ -184,27 +224,96 @@ public struct ObjectWithEveryType: ExampleClientModel { self.any = any } public init() {} - public init?(map: Map) {} - public mutating func mapping(map: Map) { - self.string <- map["string"] - self.boolean <- map["boolean"] - self.timestamp <- (map["timestamp"], __dateTransformer) - self.float32 <- map["float32"] - self.float64 <- map["float64"] - self.int8 <- map["int8"] - self.uint8 <- map["uint8"] - self.int16 <- map["int16"] - self.uint16 <- map["uint16"] - self.int32 <- map["int32"] - self.uint32 <- map["uint32"] - self.int64 <- map["int64"] - self.uint64 <- map["uint64"] - self.`enum` <- map["enum"] is String ? Enumerator(string: map["enum"] as String) : Enumerator.foo // TODO - self.object <- map["object"] // TODO - self.array <- map["array"] // TODO - self.record <- map["record"] // TODO - self.discriminator <- map["discriminator"] // TODO - self.any <- map["any"] // TODO + public init(json: JSON) { + self.string = json["string"].string ?? "" + self.boolean = json["boolean"].bool ?? false + self.timestamp = __dateFormatter.date(from: json["timestamp"].string ?? "") ?? Date.now + self.float32 = json["float32"].number?.floatValue ?? 0.0 + self.float64 = json["float64"].number?.doubleValue ?? 0.0 + self.int8 = json["int8"].number?.int8Value ?? 0 + self.uint8 = json["uint8"].number?.uint8Value ?? 0 + self.int16 = json["int16"].number?.int16Value ?? 0 + self.uint16 = json["uint16"].number?.uint16Value ?? 0 + self.int32 = json["int32"].number?.int32Value ?? 0 + self.uint32 = json["uint32"].number?.uint32Value ?? 0 + self.int64 = Int64(json["int64"].string ?? "0") ?? 0 + self.uint64 = UInt64(json["uint64"].string ?? "0") ?? 0 + self.`enum` = Enumerator(serialValue: json["enum"].string ?? "") + self.object = NestedObject(json: json["object"]) + self.array = [] + let __arrayJson = json["array"].array ?? [] + for __arrayJsonElement in __arrayJson { + self.array.append(contentsOf: [__arrayJsonElement.bool ?? false]) + } + self.record = Dictionary() + let __recordJson = json["record"].dictionary ?? Dictionary() + for __recordJsonKey in __recordJson.keys { + let __recordJsonValue = __recordJson[__recordJsonKey]?.bool ?? false + self.record[__recordJsonKey] = __recordJsonValue + } + self.discriminator = Discriminator(json: json["discriminator"]) + self.any = json["any"] + } + public init(JSONString: String) { + self.init(json: JSON(stringLiteral: JSONString)) + } + public func toJSONString() -> String { + var __json = "{" + __json += "\"string\":" + __json += serializeString(input: self.string) + __json += ",\"boolean\":" + __json += "\(self.boolean)" + __json += ",\"timestamp\":" + __json += "\"\(__dateFormatter.string(from: self.timestamp))\"" + __json += ",\"float32\":" + __json += "\(self.float32)" + __json += ",\"float64\":" + __json += "\(self.float64)" + __json += ",\"int8\":" + __json += "\(self.int8)" + __json += ",\"uint8\":" + __json += "\(self.uint8)" + __json += ",\"int16\":" + __json += "\(self.int16)" + __json += ",\"uint16\":" + __json += "\(self.uint16)" + __json += ",\"int32\":" + __json += "\(self.int32)" + __json += ",\"uint32\":" + __json += "\(self.uint32)" + __json += ",\"int64\":" + __json += "\"\(self.int64)\"" + __json += ",\"uint64\":" + __json += "\"\(self.uint64)\"" + __json += ",\"enum\":" + __json += "\"\(self.enum.serialValue())\"" + __json += ",\"object\":" + __json += self.object.toJSONString() + __json += ",\"array\":" + __json += "[" + for (__index, __element) in self.array.enumerated() { + if __index > 0 { + __json += "," + } + __json += "\(__element)" + } + __json += "]" + __json += ",\"record\":" + __json += "{" + for (__index, __key) in self.record.keys.enumerated() { + if __index > 0 { + __json += "," + } + __json += "\"\(__key)\":" + __json += "\(self.record[__key]!)" + } + __json += "}" + __json += ",\"discriminator\":" + __json += self.discriminator.toJSONString() + __json += ",\"any\":" + __json += serializeAny(input: self.any) + __json += "}" + return __json } public func toQueryString() -> String { var __queryParts: [String] = [] @@ -249,17 +358,20 @@ public struct ObjectWithEveryType: ExampleClientModel { left.array == right.array && left.record == right.record && left.discriminator == right.discriminator && - left.any as? String == right.any as? String + left.any == right.any } } -public enum Enumerator { +public enum Enumerator: ExampleClientEnum { case foo case bar case baz - public init(string: String) { - switch(string) { + public init() { + self = .foo + } + public init(serialValue: String) { + switch(serialValue) { case "FOO": self = .foo break; @@ -273,7 +385,6 @@ public enum Enumerator { self = .foo } } - public func serialValue() -> String { switch (self) { case .foo: @@ -286,24 +397,44 @@ public enum Enumerator { } } -public enum Discriminator: ExampleClientEnum { - +public enum Discriminator: ExampleClientModel { case a(DiscriminatorA) case b(DiscriminatorB) case c(DiscriminatorC) - public func toJsonString() -> String { + public init() { + self = .a(DiscriminatorA()) + } + public init(json: JSON) { + let typeName = json["typeName"].string ?? "" + switch (typeName) { + case "A": + self = .a(DiscriminatorA(json: json)) + break + case "B": + self = .b(DiscriminatorB(json: json)) + break + case "C": + self = .c(DiscriminatorC(json: json)) + break; + default: + self = .a(DiscriminatorA()) + break; + } + } + public init(JSONString: String) { + self.init(json: JSON(stringLiteral: JSONString)) + } + public func toJSONString() -> String { switch(self) { case .a(let __innerVal): - return __innerVal.toJSONString() ?? "" + return __innerVal.toJSONString() case .b(let __innerVal): - return __innerVal.toJSONString() ?? "" + return __innerVal.toJSONString() case .c(let __innerVal): - return __innerVal.toJSONString() ?? "" + return __innerVal.toJSONString() } } - - public func toQueryString() -> String { switch(self) { case .a(let __innerVal): @@ -326,12 +457,20 @@ public struct DiscriminatorA: ExampleClientModel { self.id = id } public init() {} - public init?(map: Map) {} - - public mutating func mapping(map: Map) { - self.id <- map["id"] + public init(json: JSON) { + self.id = json["id"].string ?? "" + } + public init(JSONString: String) { + self.init(json: JSON(stringLiteral: JSONString)) } + public func toJSONString() -> String { + var __json = "{" + __json += "\"id\":" + __json += serializeString(input: self.id) + __json += "}" + return __json + } public func toQueryString() -> String { var __queryParts: [String] = [] __queryParts.append("type=A") @@ -353,11 +492,21 @@ public struct DiscriminatorB: ExampleClientModel { self.name = name } public init() {} - public init?(map: Map) {} - - public mutating func mapping(map: Map) { - self.id <- map["id"] - self.name <- map["name"] + public init(json: JSON) { + self.id = json["id"].string ?? "" + self.name = json["name"].string ?? "" + } + public init(JSONString: String) { + self.init(json: JSON(stringLiteral: JSONString)) + } + public func toJSONString() -> String { + var __json = "{" + __json += "\"id\":" + __json += serializeString(input: self.id) + __json += ",\"name\":" + __json += serializeString(input: self.name) + __json += "}" + return __json } public func toQueryString() -> String { @@ -385,12 +534,25 @@ public struct DiscriminatorC: ExampleClientModel { self.date = date } public init() {} - public init?(map: Map) {} + public init(json: JSON) { + self.id = json["id"].string ?? "" + self.name = json["name"].string ?? "" + self.date = __dateFormatter.date(from: json["date"].string ?? "") ?? Date.now + } + public init(JSONString: String) { + self.init(json: JSON(stringLiteral: JSONString)) + } - public mutating func mapping(map: Map) { - self.id <- map["id"] - self.name <- map["name"] - self.date <- (map["date"], __dateTransformer) + public func toJSONString() -> String { + var __json = "{" + __json += "\"id\":" + __json += serializeString(input: self.id) + __json += ",\"name\":" + __json += serializeString(input: self.name) + __json += "\"date\":" + __json += "\"\(__dateFormatter.string(from: self.date))\"" + __json += "}" + return __json } public func toQueryString() -> String { diff --git a/languages/swift/swift-codegen-reference/Tests/BookTests.swift b/languages/swift/swift-codegen-reference/Tests/BookTests.swift index dc6c2ed0..b8b2196f 100644 --- a/languages/swift/swift-codegen-reference/Tests/BookTests.swift +++ b/languages/swift/swift-codegen-reference/Tests/BookTests.swift @@ -16,11 +16,9 @@ final class BookTests: XCTestCase { func testFromJson() throws { let bookJson: String? = try? String(contentsOfFile: location, encoding: .utf8) - let result1 = Book(JSONString: bookJson ?? "") ?? Book() - let result2: Book = Book(JSONString: control.toJSONString() ?? "") ?? Book() - XCTAssertEqual(result1, control) - XCTAssertEqual(result2, control) - XCTAssertEqual(result1, result2) + let result = Book(JSONString: bookJson ?? "") ?? Book() + XCTAssertEqual(result, control) + XCTAssertEqual(control.toJSONString(), bookJson) } func testToQueryString() throws { let expectedResult = "id=1&name=The Adventures of Tom Sawyer&createdAt=2001-01-01T16:00:00.000Z&updatedAt=2001-01-01T16:00:00.000Z" diff --git a/languages/swift/swift-codegen-reference/Tests/NestedObjectTest.swift b/languages/swift/swift-codegen-reference/Tests/NestedObjectTest.swift index 39ec126c..dfb0396f 100644 --- a/languages/swift/swift-codegen-reference/Tests/NestedObjectTest.swift +++ b/languages/swift/swift-codegen-reference/Tests/NestedObjectTest.swift @@ -16,17 +16,13 @@ final class NestedObjectTests: XCTestCase { func testFromJson() throws { let objectJson: String? = try? String(contentsOfFile: noSpecialCharsLocation, encoding: .utf8) - let result1: NestedObject = NestedObject(JSONString: objectJson ?? "") ?? NestedObject() - let result2: NestedObject = NestedObject(JSONString: noSpecialCharsControl.toJSONString() ?? "") ?? NestedObject() - XCTAssertEqual(result1, noSpecialCharsControl) - XCTAssertEqual(result2, noSpecialCharsControl) - XCTAssertEqual(result1, result2) + let result: NestedObject = NestedObject(JSONString: objectJson ?? "") + XCTAssertEqual(result, noSpecialCharsControl) + XCTAssertEqual(noSpecialCharsControl.toJSONString(), objectJson) let specialCharsObjectJson = try? String(contentsOfFile: specialCharsLocation, encoding: .utf8) - let specialCharsResult1 = NestedObject(JSONString: specialCharsObjectJson ?? "") ?? NestedObject() - let specialCharsResult2 = NestedObject(JSONString: specialCharsControl.toJSONString() ?? "") ?? NestedObject() - XCTAssertEqual(specialCharsResult1, specialCharsControl) - XCTAssertEqual(specialCharsResult2, specialCharsControl) - XCTAssertEqual(specialCharsResult1, specialCharsResult2) + let specialCharsResult = NestedObject(JSONString: specialCharsObjectJson ?? "") + XCTAssertEqual(specialCharsResult, specialCharsControl) + XCTAssertEqual(specialCharsControl.toJSONString(), specialCharsObjectJson) } func testToQueryString() throws { let expectedResult = "id=1&content=hello world" diff --git a/languages/swift/swift-codegen-reference/Tests/ObjectWithEveryTypeTest.swift b/languages/swift/swift-codegen-reference/Tests/ObjectWithEveryTypeTest.swift index ba521b82..eac58e73 100644 --- a/languages/swift/swift-codegen-reference/Tests/ObjectWithEveryTypeTest.swift +++ b/languages/swift/swift-codegen-reference/Tests/ObjectWithEveryTypeTest.swift @@ -33,10 +33,8 @@ final class ObjectWithEveryTypeTests: XCTestCase { func testFromJson() throws { let objectJson = try String(contentsOfFile: location, encoding: .utf8) - let result1 = ObjectWithEveryType(JSONString: objectJson) ?? ObjectWithEveryType() - let result2 = ObjectWithEveryType(JSONString: control.toJSONString() ?? "") ?? ObjectWithEveryType() - XCTAssertEqual(result1, control) - XCTAssertEqual(result2, control) - XCTAssertEqual(result1, result2) + let result = ObjectWithEveryType(JSONString: objectJson) ?? ObjectWithEveryType() + XCTAssertEqual(result, control) + XCTAssertEqual(control.toJSONString(), objectJson) } } \ No newline at end of file diff --git a/languages/swift/swift-codegen-reference/project.json b/languages/swift/swift-codegen-reference/project.json index 27fc2839..b877106d 100644 --- a/languages/swift/swift-codegen-reference/project.json +++ b/languages/swift/swift-codegen-reference/project.json @@ -1,5 +1,22 @@ { "name": "swift-codegen-reference", "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "targets": {} + "targets": { + "build": { + "executor": "nx:run-commands", + "cache": false, + "options": { + "command": "swift build", + "cwd": "languages/swift/swift-codegen-reference" + } + }, + "test": { + "executor": "nx:run-commands", + "cache": false, + "options": { + "command": "swift test", + "cwd": "languages/swift/swift-codegen-reference" + } + } + } }