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 Float32 decoding, add DoubleBox #138

Merged
merged 2 commits into from Oct 6, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/BoolBox.swift
Expand Up @@ -38,7 +38,7 @@ extension BoolBox: Box {
/// ---
///
/// [Schema definition](https://www.w3.org/TR/xmlschema-2/#boolean)
func xmlString() -> String? {
var xmlString: String? {
return (unboxed) ? "true" : "false"
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/Box.swift
Expand Up @@ -7,7 +7,7 @@

protocol Box {
var isNull: Bool { get }
func xmlString() -> String?
var xmlString: String? { get }
}

/// A box that only describes a single atomic value.
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/ChoiceBox.swift
Expand Up @@ -16,7 +16,7 @@ extension ChoiceBox: Box {
return false
}

func xmlString() -> String? {
var xmlString: String? {
return nil
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/DataBox.swift
Expand Up @@ -42,7 +42,7 @@ extension DataBox: Box {
return false
}

func xmlString() -> String? {
var xmlString: String? {
return xmlString(format: format)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/DateBox.swift
Expand Up @@ -84,7 +84,7 @@ extension DateBox: Box {
return false
}

func xmlString() -> String? {
var xmlString: String? {
return xmlString(format: format)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/DecimalBox.swift
Expand Up @@ -47,7 +47,7 @@ extension DecimalBox: Box {
/// ---
///
/// [Schema definition](https://www.w3.org/TR/xmlschema-2/#decimal)
func xmlString() -> String? {
var xmlString: String? {
return "\(unboxed)"
}
}
Expand Down
48 changes: 48 additions & 0 deletions Sources/XMLCoder/Auxiliaries/Box/DoubleBox.swift
@@ -0,0 +1,48 @@
//
// DoubleBox.swift
// XMLCoder
//
// Created by Max Desiatov on 05/10/2019.
//

struct DoubleBox: Equatable, ValueBox {
typealias Unboxed = Double

let unboxed: Unboxed

init(_ value: Unboxed) {
unboxed = value
}

init?(xmlString: String) {
guard let unboxed = Double(xmlString) else { return nil }

self.init(unboxed)
}
}

extension DoubleBox: Box {
var isNull: Bool {
return false
}

var xmlString: String? {
guard !unboxed.isNaN else {
return "NaN"
}

guard !unboxed.isInfinite else {
return (unboxed > 0.0) ? "INF" : "-INF"
}

return unboxed.description
}
}

extension DoubleBox: SimpleBox {}

extension DoubleBox: CustomStringConvertible {
var description: String {
return unboxed.description
}
}
10 changes: 3 additions & 7 deletions Sources/XMLCoder/Auxiliaries/Box/FloatBox.swift
Expand Up @@ -5,8 +5,8 @@
// Created by Vincent Esche on 12/17/18.
//

struct FloatBox: Equatable {
typealias Unboxed = Float64
struct FloatBox: Equatable, ValueBox {
typealias Unboxed = Float

let unboxed: Unboxed

Expand All @@ -20,10 +20,6 @@ struct FloatBox: Equatable {
}
self.init(unboxed)
}

func unbox<Float: BinaryFloatingPoint>() -> Float? {
return Float(exactly: unboxed)
}
}

extension FloatBox: Box {
Expand Down Expand Up @@ -59,7 +55,7 @@ extension FloatBox: Box {
/// ---
///
/// [Schema definition](https://www.w3.org/TR/xmlschema-2/#float)
func xmlString() -> String? {
var xmlString: String? {
guard !unboxed.isNaN else {
return "NaN"
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/IntBox.swift
Expand Up @@ -44,7 +44,7 @@ extension IntBox: Box {
/// ---
///
/// [Schema definition](https://www.w3.org/TR/xmlschema-2/#integer)
func xmlString() -> String? {
var xmlString: String? {
return unboxed.description
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/KeyedBox.swift
Expand Up @@ -43,7 +43,7 @@ extension KeyedBox: Box {
return false
}

func xmlString() -> String? {
var xmlString: String? {
return nil
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/NullBox.swift
Expand Up @@ -12,7 +12,7 @@ extension NullBox: Box {
return true
}

func xmlString() -> String? {
var xmlString: String? {
return nil
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/XMLCoder/Auxiliaries/Box/SharedBox.swift
Expand Up @@ -22,8 +22,8 @@ extension SharedBox: Box {
return unboxed.isNull
}

func xmlString() -> String? {
return unboxed.xmlString()
var xmlString: String? {
return unboxed.xmlString
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/SingleKeyedBox.swift
Expand Up @@ -18,7 +18,7 @@ extension SingleKeyedBox: Box {
return false
}

func xmlString() -> String? {
var xmlString: String? {
return nil
}
}
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/StringBox.swift
Expand Up @@ -24,7 +24,7 @@ extension StringBox: Box {
return false
}

func xmlString() -> String? {
var xmlString: String? {
return unboxed.description
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/UIntBox.swift
Expand Up @@ -47,7 +47,7 @@ extension UIntBox: Box {
/// ---
///
/// [Schema definition](https://www.w3.org/TR/xmlschema-2/#nonNegativeInteger)
func xmlString() -> String? {
var xmlString: String? {
return unboxed.description
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/URLBox.swift
Expand Up @@ -29,7 +29,7 @@ extension URLBox: Box {
return false
}

func xmlString() -> String? {
var xmlString: String? {
return unboxed.absoluteString
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMLCoder/Auxiliaries/Box/UnkeyedBox.swift
Expand Up @@ -12,7 +12,7 @@ extension Array: Box {
return false
}

func xmlString() -> String? {
var xmlString: String? {
return nil
}
}
12 changes: 12 additions & 0 deletions Sources/XMLCoder/Auxiliaries/Box/ValueBox.swift
@@ -0,0 +1,12 @@
//
// File.swift
// XMLCoder
//
// Created by Max Desiatov on 05/10/2019.
//

protocol ValueBox: SimpleBox {
associatedtype Unboxed

init(_ value: Unboxed)
}
4 changes: 2 additions & 2 deletions Sources/XMLCoder/Auxiliaries/XMLCoderElement.swift
Expand Up @@ -288,7 +288,7 @@ extension XMLCoderElement {
}

let attributes: [Attribute] = box.attributes.compactMap { key, box in
guard let value = box.xmlString() else {
guard let value = box.xmlString else {
return nil
}
return Attribute(key: key, value: value)
Expand All @@ -299,7 +299,7 @@ extension XMLCoderElement {

init(key: String, box: SimpleBox) {
self.init(key: key)
value = box.xmlString()
value = box.xmlString
}

init(key: String, box: Box) {
Expand Down
2 changes: 2 additions & 0 deletions Sources/XMLCoder/Decoder/DecodingErrorExtension.swift
Expand Up @@ -43,6 +43,8 @@ extension DecodingError {
return "an unsigned integer value"
case is FloatBox:
return "a floating-point value"
case is DoubleBox:
return "a double floating-point value"
case is UnkeyedBox:
return "a array value"
case is KeyedBox:
Expand Down
6 changes: 5 additions & 1 deletion Sources/XMLCoder/Decoder/SingleValueDecodingContainer.swift
Expand Up @@ -31,7 +31,11 @@ extension XMLDecoderImplementation: SingleValueDecodingContainer {
return try unbox(try topContainer())
}

public func decode<T: BinaryFloatingPoint & Decodable>(_: T.Type) throws -> T {
public func decode(_: Float.Type) throws -> Float {
return try unbox(try topContainer())
}

public func decode(_: Double.Type) throws -> Double {
return try unbox(try topContainer())
}

Expand Down
22 changes: 13 additions & 9 deletions Sources/XMLCoder/Decoder/XMLDecoderImplementation.swift
Expand Up @@ -286,22 +286,26 @@ extension XMLDecoderImplementation {
return uint
}

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

guard let floatBox = FloatBox(xmlString: string) else {
throw DecodingError.typeMismatch(at: codingPath, expectation: T.self, reality: box)
throw DecodingError.typeMismatch(at: codingPath, expectation: Float.self, reality: box)
}

guard let float: T = floatBox.unbox() else {
throw DecodingError.dataCorrupted(DecodingError.Context(
codingPath: codingPath,
debugDescription: "Parsed XML number <\(string)> does not fit in \(T.self)."
))
return floatBox.unboxed
}

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

guard let doubleBox = DoubleBox(xmlString: string) else {
throw DecodingError.typeMismatch(at: codingPath, expectation: Double.self, reality: box)
}

return float
return doubleBox.unboxed
}

func unbox(_ box: Box) throws -> String {
Expand Down
23 changes: 18 additions & 5 deletions Sources/XMLCoder/Encoder/XMLEncoderImplementation.swift
Expand Up @@ -165,13 +165,26 @@ extension XMLEncoderImplementation {
return UIntBox(value)
}

func box<T: BinaryFloatingPoint & Encodable>(_ value: T) throws -> SimpleBox {
func box(_ value: Float) throws -> SimpleBox {
return try box(value, FloatBox.self)
}

func box(_ value: Double) throws -> SimpleBox {
return try box(value, DoubleBox.self)
}

func box<T: BinaryFloatingPoint & Encodable, B: ValueBox>(
_ value: T,
_: B.Type
) throws -> SimpleBox where B.Unboxed == T {
guard value.isInfinite || value.isNaN else {
return FloatBox(value)
return B(value)
}
guard case let .convertToString(positiveInfinity: posInfString,
negativeInfinity: negInfString,
nan: nanString) = options.nonConformingFloatEncodingStrategy else {
guard case let .convertToString(
positiveInfinity: posInfString,
negativeInfinity: negInfString,
nan: nanString
) = options.nonConformingFloatEncodingStrategy else {
throw EncodingError._invalidFloatingPointValue(value, at: codingPath)
}
if value == T.infinity {
Expand Down
2 changes: 1 addition & 1 deletion Tests/XMLCoderTests/Box/BoolBoxTests.swift
Expand Up @@ -36,7 +36,7 @@ class BoolBoxTests: XCTestCase {

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

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

guard let box = boxOrNil else { continue }

XCTAssertEqual(box.xmlString(), xmlString)
XCTAssertEqual(box.xmlString, xmlString)
}
}

Expand Down
8 changes: 4 additions & 4 deletions Tests/XMLCoderTests/Box/DateBoxTests.swift
Expand Up @@ -48,7 +48,7 @@ class DateBoxTests: XCTestCase {

guard let box = boxOrNil else { continue }

XCTAssertEqual(box.xmlString(), xmlString)
XCTAssertEqual(box.xmlString, xmlString)
}
}

Expand All @@ -65,7 +65,7 @@ class DateBoxTests: XCTestCase {

guard let box = boxOrNil else { continue }

XCTAssertEqual(box.xmlString(), xmlString)
XCTAssertEqual(box.xmlString, xmlString)
}
}

Expand All @@ -80,7 +80,7 @@ class DateBoxTests: XCTestCase {

guard let box = boxOrNil else { continue }

XCTAssertEqual(box.xmlString(), xmlString)
XCTAssertEqual(box.xmlString, xmlString)
}
}

Expand All @@ -95,7 +95,7 @@ class DateBoxTests: XCTestCase {

guard let box = boxOrNil else { continue }

XCTAssertEqual(box.xmlString(), xmlString)
XCTAssertEqual(box.xmlString, xmlString)
}
}

Expand Down