Experiementing with using always strings for Decimal

This commit is contained in:
Ralph Kuepper 2019-10-22 18:01:31 +02:00
parent 4cb41f0d28
commit 7b88fc5974
5 changed files with 47 additions and 8 deletions

View File

@ -16,6 +16,8 @@ internal final class _JSONDecoder: Decoder {
throw DecodingError.expectedType([String: JSON].self, at: self.codingPath, from: self.json)
}
print("container")
let container = _JSONKeyedValueDecoder<Key>.init(at: self.codingPath, wrapping: json)
return KeyedDecodingContainer(container)
}
@ -25,6 +27,8 @@ internal final class _JSONDecoder: Decoder {
throw DecodingError.expectedType([JSON].self, at: self.codingPath, from: self.json)
}
print("unkey container")
return _JSONUnkeyedDecoder(at: self.codingPath, wrapping: json)
}
@ -33,11 +37,13 @@ internal final class _JSONDecoder: Decoder {
}
static func decode<T>(_ type: T.Type, from json: JSON)throws -> T where T: Decodable {
print("decoding: ", type, json)
if let value = (type as? LosslessJSONConvertible.Type)?.init(json: json) {
return value as! T
}
print("still here")
let decoder = self.init(codingPath: [], json: json)
print("still")
return try T.init(from: decoder)
}
}

View File

@ -39,6 +39,7 @@ internal struct _JSONKeyedValueDecoder<K: CodingKey>: KeyedDecodingContainerProt
guard let json = self.json[key.stringValue] else {
throw DecodingError.badKey(key, at: self.codingPath)
}
print("decoding again now: ", type, key)
return try json.value(for: type, at: self.codingPath)
}

View File

@ -72,8 +72,12 @@ extension JSON {
case is Double.Type:
return try self.number(at: path, as: Double.self) as! T
case is Decimal.Type:
if case let .number(.decimal(value)) = self { return value as! T }
throw DecodingError.expectedType(Decimal.self, at: path, from: self)
guard case let JSON.string(value) = self else {
throw error
}
return Decimal(string: value ) as! T
//if case let .number(.decimal(value)) = self { return value as! T }
//throw DecodingError.expectedType(Decimal.self, at: path, from: self)
case is String.Type:
guard case let JSON.string(value) = self else {
throw error

View File

@ -92,13 +92,13 @@ extension Decimal: JSONRepresentable {
/// See `SafeJSONRepresentable.json`.
public var json: JSON {
return .number(.decimal(self))
return .string(NSDecimalNumber(decimal: self).stringValue)
}
/// See `LosslessJSONConvertible.init(json:)`.
public init?(json: JSON) {
guard let decimal = json.decimal else { return nil }
self = decimal
guard let decimal = json.string else { return nil }
self = Decimal(string: decimal)!
}
}

View File

@ -1,13 +1,23 @@
import XCTest
import JSON
struct DData: Codable {
var d1: Decimal
var d2: Decimal
}
final class DecimalTests: XCTestCase {
var testJson = """
{"d2":"1.1234","d1":"3.14"}
"""
func testDecimalEncode() throws {
let decJSON = try Decimal(3.14).json()
let numJSON = try Num(value: 3.14).json()
XCTAssertEqual(decJSON, .number(.decimal(3.14)))
XCTAssertEqual(numJSON, .object(["value": .number(.decimal(3.14))]))
XCTAssertEqual(decJSON, .string("3.14"))
XCTAssertEqual(numJSON, .object(["value": .string("3.14")]))
}
func testDecimalDecode() throws {
@ -20,6 +30,24 @@ final class DecimalTests: XCTestCase {
XCTAssertEqual(dec, 3.14)
XCTAssertEqual(num, Num(value: 3.14))
}
func testStringDecoding() throws {
let json = try JSON(data: testJson.data(using: .utf8)!)
let dd = try JSONCoder.decode(DData.self, from: json)
XCTAssertEqual(dd.d1,3.14)
XCTAssertEqual(dd.d2,1.1234)
}
func testStringEncoding() throws {
let dd = DData(d1: 3.14, d2: 1.1234)
let json = try JSONCoder.encode(dd)
let stringData = try JSONEncoder().encode(json)
let string = String(data: stringData, encoding: .utf8)!
XCTAssertEqual(testJson, string)
}
}
fileprivate struct Num: Codable, Equatable {