diff --git a/README.md b/README.md index b2da0082..675436ef 100644 --- a/README.md +++ b/README.md @@ -314,7 +314,7 @@ struct Book: XMLIndexerDeserializable { let price: Double let year: Int let amount: Int? - + static func deserialize(node: XMLIndexer) throws -> Book { return try Book( title: node["title"].value(), @@ -334,7 +334,7 @@ let books: [Book] = try xml["root"]["books"]["book"].value() Types Conversion -Build-in, leaf-nodes converters support `Int`, `Double`, `Float` and `String` values (both non- and -optional variants). Custom converters can be added by implementing `XMLElementDeserializable`. +Build-in, leaf-nodes converters support `Int`, `Double`, `Float`, `Bool`, and `String` values (both non- and -optional variants). Custom converters can be added by implementing `XMLElementDeserializable`. You can convert any XML to your custom type by implementing `XMLIndexerDeserializable`. diff --git a/Source/SWXMLHash+TypeConversion.swift b/Source/SWXMLHash+TypeConversion.swift index d7320936..b04be832 100644 --- a/Source/SWXMLHash+TypeConversion.swift +++ b/Source/SWXMLHash+TypeConversion.swift @@ -325,3 +325,19 @@ extension Float: XMLElementDeserializable { return value } } + +extension Bool: XMLElementDeserializable { + /** + Attempts to deserialize XML element content to a Bool. This uses NSString's 'boolValue' described + [here](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/#//apple_ref/occ/instp/NSString/boolValue) + + - parameters: + - element: the XMLElement to be deserialized + - throws: an XMLDeserializationError.TypeConversionFailed if the element cannot be deserialized + - returns: the deserialized Bool value + */ + public static func deserialize(element: XMLElement) throws -> Bool { + let value = Bool(NSString(string: try element.nonEmptyTextOrThrow()).boolValue) + return value + } +} diff --git a/Tests/SWXMLHashSpecs.swift b/Tests/SWXMLHashSpecs.swift index 45287c56..b46d793b 100644 --- a/Tests/SWXMLHashSpecs.swift +++ b/Tests/SWXMLHashSpecs.swift @@ -312,6 +312,8 @@ class SWXMLHashTypeConversionSpecs: QuickSpec { " 100" + " 100.45" + " 44.12" + + " 0" + + " true" + " " + " " + " the name of basic item" + @@ -461,6 +463,45 @@ class SWXMLHashTypeConversionSpecs: QuickSpec { } } + describe("when parsing Bool") { + it("should convert `value` to non-optional") { + let value1: Bool = try! parser!["root"]["bool1"].value() + let value2: Bool = try! parser!["root"]["bool2"].value() + expect(value1) == false + expect(value2) == true + } + + it("should throw when converting `empty` to non-optional") { + expect { try (parser!["root"]["empty"].value() as Bool) }.to( + throwError(errorType: XMLDeserializationError.self) + ) + } + + it("should throw when converting `missing` to non-optional") { + expect { try (parser!["root"]["missing"].value() as Bool) }.to( + throwError(errorType: XMLDeserializationError.self) + ) + } + + it("should convert `value` to optional") { + let value1: Bool? = try! parser!["root"]["bool1"].value() + expect(value1) == false + let value2: Bool? = try! parser!["root"]["bool2"].value() + expect(value2) == true + } + + it("should convert `empty` to optional") { + expect { try (parser!["root"]["empty"].value() as Bool?) }.to( + throwError(errorType: XMLDeserializationError.self) + ) + } + + it("should convert `missing` to optional") { + let value: Bool? = try! parser!["root"]["missing"].value() + expect(value).to(beNil()) + } + } + describe("when parsing BasicItem") { let correctBasicItem = BasicItem(name: "the name of basic item", price: 99.14)