diff --git a/Sources/XMLCoder/Auxiliaries/XMLCoderElement.swift b/Sources/XMLCoder/Auxiliaries/XMLCoderElement.swift index acc800a8..97d43e78 100644 --- a/Sources/XMLCoder/Auxiliaries/XMLCoderElement.swift +++ b/Sources/XMLCoder/Auxiliaries/XMLCoderElement.swift @@ -103,10 +103,13 @@ struct XMLCoderElement: Equatable { prettyPrinted: Bool ) -> String { var string = "" + // Fix added for empty key adjustment in `UnkeyedBox` taking static func builder + let nonEmptyKey = element.key != "" + let level = nonEmptyKey ? level + 1 : level string += element._toXMLString( - indented: level + 1, withCDATA: cdata, formatting: formatting + indented: level, withCDATA: cdata, formatting: formatting ) - string += prettyPrinted ? "\n" : "" + string += (prettyPrinted && nonEmptyKey) ? "\n" : "" return string } @@ -226,7 +229,9 @@ struct XMLCoderElement: Equatable { string += "" } } else if !elements.isEmpty { - string += prettyPrinted ? ">\n" : ">" + if !key.isEmpty { + string += prettyPrinted ? ">\n" : ">" + } formatXMLElements(formatting, &string, level, cdata, prettyPrinted) string += indentation @@ -244,6 +249,12 @@ struct XMLCoderElement: Equatable { // MARK: - Convenience Initializers extension XMLCoderElement { + static func containsChoice(key: String, box: UnkeyedBox) -> XMLCoderElement { + return XMLCoderElement(key: key, elements: box.map { + XMLCoderElement(key: "", box: $0) + }) + } + init(key: String, box: UnkeyedBox) { self.init(key: key, elements: box.map { XMLCoderElement(key: key, box: $0) diff --git a/Sources/XMLCoder/Encoder/XMLChoiceEncodable.swift b/Sources/XMLCoder/Encoder/XMLChoiceEncodable.swift index 81a37b83..2186255a 100644 --- a/Sources/XMLCoder/Encoder/XMLChoiceEncodable.swift +++ b/Sources/XMLCoder/Encoder/XMLChoiceEncodable.swift @@ -6,3 +6,7 @@ // public protocol XMLChoiceEncodable: Encodable {} + +public protocol ArrayOfXMLChoiceEncodable {} + +extension Array: ArrayOfXMLChoiceEncodable where Element: XMLChoiceEncodable {} diff --git a/Sources/XMLCoder/Encoder/XMLEncoder.swift b/Sources/XMLCoder/Encoder/XMLEncoder.swift index 7ba007b2..94788070 100644 --- a/Sources/XMLCoder/Encoder/XMLEncoder.swift +++ b/Sources/XMLCoder/Encoder/XMLEncoder.swift @@ -337,7 +337,11 @@ open class XMLEncoder { if let keyedBox = topLevel as? KeyedBox { elementOrNone = XMLCoderElement(key: rootKey, box: keyedBox) } else if let unkeyedBox = topLevel as? UnkeyedBox { - elementOrNone = XMLCoderElement(key: rootKey, box: unkeyedBox) + if T.self is ArrayOfXMLChoiceEncodable.Type { + elementOrNone = XMLCoderElement.containsChoice(key: rootKey, box: unkeyedBox) + } else { + elementOrNone = XMLCoderElement(key: rootKey, box: unkeyedBox) + } } else { fatalError("Unrecognized top-level element of type: \(type(of: topLevel))") } diff --git a/Tests/XMLCoderTests/CompositeChoiceTests.swift b/Tests/XMLCoderTests/CompositeChoiceTests.swift index 2c58982e..c941805c 100644 --- a/Tests/XMLCoderTests/CompositeChoiceTests.swift +++ b/Tests/XMLCoderTests/CompositeChoiceTests.swift @@ -22,7 +22,6 @@ private enum IntOrStringWrapper: Equatable { } extension IntOrStringWrapper: XMLChoiceCodable { - enum CodingKeys: String, CodingKey { case int case string @@ -38,7 +37,7 @@ extension IntOrStringWrapper: XMLChoiceCodable { } func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) + var container = encoder.container(keyedBy: CodingKeys.self) switch self { case let .int(value): try container.encode(value, forKey: .int) @@ -49,7 +48,6 @@ extension IntOrStringWrapper: XMLChoiceCodable { } class CompositeChoiceTests: XCTestCase { - func testIntOrStringWrapper() throws { let xml = """ diff --git a/Tests/XMLCoderTests/SimpleChoiceTests.swift b/Tests/XMLCoderTests/SimpleChoiceTests.swift index 34bd4974..edccd9e7 100644 --- a/Tests/XMLCoderTests/SimpleChoiceTests.swift +++ b/Tests/XMLCoderTests/SimpleChoiceTests.swift @@ -14,7 +14,6 @@ private enum IntOrString: Equatable { } extension IntOrString: XMLChoiceCodable { - enum CodingKeys: String, CodingKey { case int case string @@ -41,7 +40,6 @@ extension IntOrString: XMLChoiceCodable { } class SimpleChoiceTests: XCTestCase { - func testIntOrStringIntDecoding() throws { let xml = "42" let result = try XMLDecoder().decode(IntOrString.self, from: xml.data(using: .utf8)!) diff --git a/XMLCoder.xcodeproj/xcshareddata/xcbaselines/XMLCoder::XMLCoderTests.xcbaseline/726F61F1-369A-4FE6-9D1D-BEC88E5CB1DC.plist b/XMLCoder.xcodeproj/xcshareddata/xcbaselines/XMLCoder::XMLCoderTests.xcbaseline/726F61F1-369A-4FE6-9D1D-BEC88E5CB1DC.plist new file mode 100644 index 00000000..9f3b9f2c --- /dev/null +++ b/XMLCoder.xcodeproj/xcshareddata/xcbaselines/XMLCoder::XMLCoderTests.xcbaseline/726F61F1-369A-4FE6-9D1D-BEC88E5CB1DC.plist @@ -0,0 +1,232 @@ + + + + + classNames + + BenchmarkTests + + testDecodeArrays() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.45609 + baselineIntegrationDisplayName + Local Baseline + + + testDecodeBools() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.064437 + baselineIntegrationDisplayName + Local Baseline + + + testDecodeDatas() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.083191 + baselineIntegrationDisplayName + Local Baseline + + + testDecodeDates() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.061247 + baselineIntegrationDisplayName + Local Baseline + + + testDecodeDecimals() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.049022 + baselineIntegrationDisplayName + Local Baseline + + + testDecodeDictionaries() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.22164 + baselineIntegrationDisplayName + Local Baseline + + + testDecodeFloats() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.0426 + baselineIntegrationDisplayName + Local Baseline + + + testDecodeInts() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.040157 + baselineIntegrationDisplayName + Local Baseline + + + testDecodeNulls() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.031343 + baselineIntegrationDisplayName + Local Baseline + + + testDecodeUInts() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.041441 + baselineIntegrationDisplayName + Local Baseline + + + testDecodeURLs() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.047946 + baselineIntegrationDisplayName + Local Baseline + + + testEncodeArrays() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.088624 + baselineIntegrationDisplayName + Local Baseline + + + testEncodeBools() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.016727 + baselineIntegrationDisplayName + Local Baseline + + + testEncodeDatas() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.022805 + baselineIntegrationDisplayName + Local Baseline + + + testEncodeDates() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.02052 + baselineIntegrationDisplayName + Local Baseline + + + testEncodeDecimals() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.016909 + baselineIntegrationDisplayName + Local Baseline + + + testEncodeDictionaries() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.11651 + baselineIntegrationDisplayName + Local Baseline + + + testEncodeFloats() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.018687 + baselineIntegrationDisplayName + Local Baseline + + + testEncodeInts() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.017093 + baselineIntegrationDisplayName + Local Baseline + + + testEncodeNulls() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.0073608 + baselineIntegrationDisplayName + Local Baseline + + + testEncodeUInts() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.017129 + baselineIntegrationDisplayName + Local Baseline + + + testEncodeURLs() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.020648 + baselineIntegrationDisplayName + Local Baseline + + + + + + diff --git a/XMLCoder.xcodeproj/xcshareddata/xcbaselines/XMLCoder::XMLCoderTests.xcbaseline/Info.plist b/XMLCoder.xcodeproj/xcshareddata/xcbaselines/XMLCoder::XMLCoderTests.xcbaseline/Info.plist index 2a9e9b9f..ef4ca520 100644 --- a/XMLCoder.xcodeproj/xcshareddata/xcbaselines/XMLCoder::XMLCoderTests.xcbaseline/Info.plist +++ b/XMLCoder.xcodeproj/xcshareddata/xcbaselines/XMLCoder::XMLCoderTests.xcbaseline/Info.plist @@ -4,6 +4,30 @@ runDestinationsByUUID + 726F61F1-369A-4FE6-9D1D-BEC88E5CB1DC + + localComputer + + busSpeedInMHz + 100 + cpuCount + 1 + cpuKind + Intel Core i5 + cpuSpeedInMHz + 3100 + logicalCPUCoresPerPackage + 4 + modelCode + MacBookPro14,2 + physicalCPUCoresPerPackage + 2 + platformIdentifier + com.apple.platform.macosx + + targetArchitecture + x86_64 + 76E090BF-7AFE-4988-A06A-3C423396A4A4 localComputer