Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix decoding empty element as optional #92

Merged
merged 6 commits into from May 1, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 0 additions & 4 deletions Sources/XMLCoder/Auxiliaries/Box/BoolBox.swift
Expand Up @@ -21,10 +21,6 @@ struct BoolBox: Equatable {
case _: return nil
}
}

func unbox() -> Unboxed {
return unboxed
}
}

extension BoolBox: Box {
Expand Down
4 changes: 0 additions & 4 deletions Sources/XMLCoder/Auxiliaries/Box/DataBox.swift
Expand Up @@ -29,10 +29,6 @@ struct DataBox: Equatable {
self.init(data, format: .base64)
}

func unbox() -> Unboxed {
return unboxed
}

func xmlString(format: Format) -> String {
switch format {
case .base64:
Expand Down
4 changes: 0 additions & 4 deletions Sources/XMLCoder/Auxiliaries/Box/DateBox.swift
Expand Up @@ -59,10 +59,6 @@ struct DateBox: Equatable {
self.init(date, format: .formatter(formatter))
}

func unbox() -> Unboxed {
return unboxed
}

func xmlString(format: Format) -> String {
switch format {
case .secondsSince1970:
Expand Down
4 changes: 0 additions & 4 deletions Sources/XMLCoder/Auxiliaries/Box/DecimalBox.swift
Expand Up @@ -22,10 +22,6 @@ struct DecimalBox: Equatable {
}
self.init(unboxed)
}

func unbox() -> Unboxed {
return unboxed
}
}

extension DecimalBox: Box {
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/KeyedBox.swift
Expand Up @@ -16,7 +16,7 @@ struct KeyedBox {
var elements = Elements()
var attributes = Attributes()

func unbox() -> (elements: Elements, attributes: Attributes) {
var unboxed: (elements: Elements, attributes: Attributes) {
return (
elements: elements,
attributes: attributes
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/SharedBox.swift
Expand Up @@ -6,7 +6,7 @@
//

class SharedBox<Unboxed: Box> {
fileprivate var unboxed: Unboxed
private(set) var unboxed: Unboxed

init(_ wrapped: Unboxed) {
unboxed = wrapped
Expand Down
4 changes: 0 additions & 4 deletions Sources/XMLCoder/Auxiliaries/Box/StringBox.swift
Expand Up @@ -17,10 +17,6 @@ struct StringBox: Equatable {
init(xmlString: Unboxed) {
self.init(xmlString)
}

func unbox() -> Unboxed {
return unboxed
}
}

extension StringBox: Box {
Expand Down
4 changes: 0 additions & 4 deletions Sources/XMLCoder/Auxiliaries/Box/URLBox.swift
Expand Up @@ -22,10 +22,6 @@ struct URLBox: Equatable {
}
self.init(unboxed)
}

func unbox() -> Unboxed {
return unboxed
}
}

extension URLBox: Box {
Expand Down
4 changes: 0 additions & 4 deletions Sources/XMLCoder/Auxiliaries/Box/UnkeyedBox.swift
Expand Up @@ -29,10 +29,6 @@ struct UnkeyedBox {
self.unboxed = unboxed
}

func unbox() -> Unboxed {
return unboxed
}

mutating func append(_ newElement: Element) {
unboxed.append(newElement)
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/XMLCoder/Auxiliaries/XMLCoderElement.swift
Expand Up @@ -256,7 +256,7 @@ extension XMLCoderElement {

switch box {
case let sharedUnkeyedBox as SharedBox<UnkeyedBox>:
let box = sharedUnkeyedBox.unbox()
let box = sharedUnkeyedBox.unboxed
elements.append(contentsOf: box.map {
XMLCoderElement(key: key, box: $0)
})
Expand All @@ -266,7 +266,7 @@ extension XMLCoderElement {
XMLCoderElement(key: key, box: $0)
})
case let sharedKeyedBox as SharedBox<KeyedBox>:
let box = sharedKeyedBox.unbox()
let box = sharedKeyedBox.unboxed
elements.append(XMLCoderElement(key: key, box: box))
case let keyedBox as KeyedBox:
elements.append(XMLCoderElement(key: key, box: keyedBox))
Expand Down Expand Up @@ -297,9 +297,9 @@ extension XMLCoderElement {
init(key: String, box: Box) {
switch box {
case let sharedUnkeyedBox as SharedBox<UnkeyedBox>:
self.init(key: key, box: sharedUnkeyedBox.unbox())
self.init(key: key, box: sharedUnkeyedBox.unboxed)
case let sharedKeyedBox as SharedBox<KeyedBox>:
self.init(key: key, box: sharedKeyedBox.unbox())
self.init(key: key, box: sharedKeyedBox.unboxed)
case let unkeyedBox as UnkeyedBox:
self.init(key: key, box: unkeyedBox)
case let keyedBox as KeyedBox:
Expand Down
55 changes: 33 additions & 22 deletions Sources/XMLCoder/Decoder/XMLDecoderImplementation.swift
Expand Up @@ -168,29 +168,29 @@ extension XMLDecoderImplementation {

func unbox(_ box: Box) throws -> Bool {
let stringBox: StringBox = try typedBox(box, for: Bool.self)
let string = stringBox.unbox()
let string = stringBox.unboxed

guard let boolBox = BoolBox(xmlString: string) else {
throw DecodingError._typeMismatch(at: codingPath, expectation: Bool.self, reality: box)
}

return boolBox.unbox()
return boolBox.unboxed
}

func unbox(_ box: Box) throws -> Decimal {
let stringBox: StringBox = try typedBox(box, for: Decimal.self)
let string = stringBox.unbox()
let string = stringBox.unboxed

guard let decimalBox = DecimalBox(xmlString: string) else {
throw DecodingError._typeMismatch(at: codingPath, expectation: Decimal.self, reality: box)
}

return decimalBox.unbox()
return decimalBox.unboxed
}

func unbox<T: BinaryInteger & SignedInteger & Decodable>(_ box: Box) throws -> T {
let stringBox: StringBox = try typedBox(box, for: T.self)
let string = stringBox.unbox()
let string = stringBox.unboxed

guard let intBox = IntBox(xmlString: string) else {
throw DecodingError._typeMismatch(at: codingPath, expectation: T.self, reality: box)
Expand All @@ -208,7 +208,7 @@ extension XMLDecoderImplementation {

func unbox<T: BinaryInteger & UnsignedInteger & Decodable>(_ box: Box) throws -> T {
let stringBox: StringBox = try typedBox(box, for: T.self)
let string = stringBox.unbox()
let string = stringBox.unboxed

guard let uintBox = UIntBox(xmlString: string) else {
throw DecodingError._typeMismatch(at: codingPath, expectation: T.self, reality: box)
Expand All @@ -226,7 +226,7 @@ extension XMLDecoderImplementation {

func unbox<T: BinaryFloatingPoint & Decodable>(_ box: Box) throws -> T {
let stringBox: StringBox = try typedBox(box, for: T.self)
let string = stringBox.unbox()
let string = stringBox.unboxed

guard let floatBox = FloatBox(xmlString: string) else {
throw DecodingError._typeMismatch(at: codingPath, expectation: T.self, reality: box)
Expand All @@ -244,7 +244,7 @@ extension XMLDecoderImplementation {

func unbox(_ box: Box) throws -> String {
let stringBox: StringBox = try typedBox(box, for: String.self)
let string = stringBox.unbox()
let string = stringBox.unboxed

return string
}
Expand All @@ -258,48 +258,48 @@ extension XMLDecoderImplementation {

case .secondsSince1970:
let stringBox: StringBox = try typedBox(box, for: Date.self)
let string = stringBox.unbox()
let string = stringBox.unboxed

guard let dateBox = DateBox(secondsSince1970: string) else {
throw DecodingError.dataCorrupted(DecodingError.Context(
codingPath: codingPath,
debugDescription: "Expected date string to be formatted in seconds since 1970."
))
}
return dateBox.unbox()
return dateBox.unboxed
case .millisecondsSince1970:
let stringBox: StringBox = try typedBox(box, for: Date.self)
let string = stringBox.unbox()
let string = stringBox.unboxed

guard let dateBox = DateBox(millisecondsSince1970: string) else {
throw DecodingError.dataCorrupted(DecodingError.Context(
codingPath: codingPath,
debugDescription: "Expected date string to be formatted in milliseconds since 1970."
))
}
return dateBox.unbox()
return dateBox.unboxed
case .iso8601:
let stringBox: StringBox = try typedBox(box, for: Date.self)
let string = stringBox.unbox()
let string = stringBox.unboxed

guard let dateBox = DateBox(iso8601: string) else {
throw DecodingError.dataCorrupted(DecodingError.Context(
codingPath: codingPath,
debugDescription: "Expected date string to be ISO8601-formatted."
))
}
return dateBox.unbox()
return dateBox.unboxed
case let .formatted(formatter):
let stringBox: StringBox = try typedBox(box, for: Date.self)
let string = stringBox.unbox()
let string = stringBox.unboxed

guard let dateBox = DateBox(xmlString: string, formatter: formatter) else {
throw DecodingError.dataCorrupted(DecodingError.Context(
codingPath: codingPath,
debugDescription: "Date string does not match format expected by formatter."
))
}
return dateBox.unbox()
return dateBox.unboxed
case let .custom(closure):
storage.push(container: box)
defer { storage.popContainer() }
Expand All @@ -315,15 +315,15 @@ extension XMLDecoderImplementation {
return try Data(from: self)
case .base64:
let stringBox: StringBox = try typedBox(box, for: Data.self)
let string = stringBox.unbox()
let string = stringBox.unboxed

guard let dataBox = DataBox(base64: string) else {
throw DecodingError.dataCorrupted(DecodingError.Context(
codingPath: codingPath,
debugDescription: "Encountered Data is not valid Base64"
))
}
return dataBox.unbox()
return dataBox.unboxed
case let .custom(closure):
storage.push(container: box)
defer { storage.popContainer() }
Expand All @@ -333,7 +333,7 @@ extension XMLDecoderImplementation {

func unbox(_ box: Box) throws -> URL {
let stringBox: StringBox = try typedBox(box, for: URL.self)
let string = stringBox.unbox()
let string = stringBox.unboxed

guard let urlBox = URLBox(xmlString: string) else {
throw DecodingError.dataCorrupted(DecodingError.Context(
Expand All @@ -342,7 +342,7 @@ extension XMLDecoderImplementation {
))
}

return urlBox.unbox()
return urlBox.unboxed
}

private struct TypeMismatch: Error {}
Expand All @@ -369,8 +369,19 @@ extension XMLDecoderImplementation {
decoded = value
} else {
storage.push(container: box)
decoded = try type.init(from: self)
storage.popContainer()
defer { storage.popContainer() }

do {
decoded = try type.init(from: self)
} catch {
guard case DecodingError.valueNotFound = error,
let type = type as? AnyOptional.Type,
let result = type.init() as? T else {
throw error
}

return result
}
}

guard let result = decoded else {
Expand Down
2 changes: 1 addition & 1 deletion Tests/XMLCoderTests/Box/BoolBoxTests.swift
Expand Up @@ -24,7 +24,7 @@ class BoolBoxTests: XCTestCase {

for unboxed in values {
let box = Boxed(unboxed)
XCTAssertEqual(box.unbox(), unboxed)
XCTAssertEqual(box.unboxed, unboxed)
}
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/XMLCoderTests/Box/DataBoxTests.swift
Expand Up @@ -24,7 +24,7 @@ class DataBoxTests: XCTestCase {

for unboxed in values {
let box = Boxed(unboxed, format: .base64)
XCTAssertEqual(box.unbox(), unboxed)
XCTAssertEqual(box.unboxed, unboxed)
}
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/XMLCoderTests/Box/DateBoxTests.swift
Expand Up @@ -31,7 +31,7 @@ class DateBoxTests: XCTestCase {

for unboxed in values {
let box = Boxed(unboxed, format: .iso8601)
XCTAssertEqual(box.unbox(), unboxed)
XCTAssertEqual(box.unboxed, unboxed)
}
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/XMLCoderTests/Box/DecimalBoxTests.swift
Expand Up @@ -26,7 +26,7 @@ class DecimalBoxTests: XCTestCase {

for unboxed in values {
let box = Boxed(unboxed)
XCTAssertEqual(box.unbox(), unboxed)
XCTAssertEqual(box.unboxed, unboxed)
}
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/XMLCoderTests/Box/KeyedBoxTests.swift
Expand Up @@ -22,7 +22,7 @@ class KeyedBoxTests: XCTestCase {
}

func testUnbox() {
let (elements, attributes) = box.unbox()
let (elements, attributes) = box.unboxed

XCTAssertEqual(elements.count, 2)
XCTAssertEqual(elements["foo"] as? StringBox, StringBox("bar"))
Expand Down
2 changes: 1 addition & 1 deletion Tests/XMLCoderTests/Box/SharedBoxTests.swift
Expand Up @@ -12,7 +12,7 @@ class SharedBoxTests: XCTestCase {
func testInit() {
let box = SharedBox(BoolBox(false))
box.withShared { shared in
XCTAssertFalse(shared.unbox())
XCTAssertFalse(shared.unboxed)
}
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/XMLCoderTests/Box/StringBoxTests.swift
Expand Up @@ -27,7 +27,7 @@ class StringBoxTests: XCTestCase {

for unboxed in values {
let box = Boxed(unboxed)
XCTAssertEqual(box.unbox(), unboxed)
XCTAssertEqual(box.unboxed, unboxed)
}
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/XMLCoderTests/Box/URLBoxTests.swift
Expand Up @@ -24,7 +24,7 @@ class URLBoxTests: XCTestCase {

for unboxed in values {
let box = Boxed(unboxed)
XCTAssertEqual(box.unbox(), unboxed)
XCTAssertEqual(box.unboxed, unboxed)
}
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/XMLCoderTests/Box/UnkeyedBoxTests.swift
Expand Up @@ -19,7 +19,7 @@ class UnkeyedBoxTests: XCTestCase {
}

func testUnbox() {
let unboxed = box.unbox()
let unboxed = box.unboxed
XCTAssertEqual(unboxed.count, 2)
XCTAssertEqual(unboxed[0] as? StringBox, StringBox("foo"))
XCTAssertEqual(unboxed[1] as? IntBox, IntBox(42))
Expand Down