Skip to content

Commit 2857cd4

Browse files
author
Kevin Ballard
committed
Convert decimal support over to Decimal
Swift exposes all of the normal floating-point operations on `Decimal`, so we're using that for our decimal number support now. It's easy to convert that to `NSDecimalNumber` if desired.
1 parent fc5dac0 commit 2857cd4

12 files changed

Lines changed: 438 additions & 186 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ Unless you explicitly state otherwise, any contribution intentionally submitted
250250

251251
#### Development
252252

253-
* Add full support for decimal numbers (on supported platforms). This takes the form of a new `JSON` variant `.decimal`, any relevant accessors, and full parsing/decoding support with the new option `.useDecimalNumbers`. With this option, any number that would have been decoded as a `Double` will be decoded as an `NSDecimalNumber` instead.
253+
* Add full support for decimal numbers (on supported platforms). This takes the form of a new `JSON` variant `.decimal`, any relevant accessors, and full parsing/decoding support with the new option `.useDecimals`. With this option, any number that would have been decoded as a `Double` will be decoded as a `Decimal` instead.
254254
* Add a set of `forEach` accessors for working with arrays, similar to the existing `map` and `flatMap` accessors.
255255

256256
#### v1.2.1 (2016-10-27)

Sources/Accessors.swift

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
#if os(iOS) || os(OSX) || os(watchOS) || os(tvOS)
1616
import class Foundation.NSDecimalNumber
17-
import class Foundation.NSNumber
17+
import struct Foundation.Decimal
1818
#endif
1919

2020
public extension JSON {
@@ -59,15 +59,15 @@ public extension JSON {
5959
}
6060

6161
/// Returns `true` iff the receiver is a `.decimal`.
62-
var isDecimalNumber: Bool {
62+
var isDecimal: Bool {
6363
switch self {
6464
case .decimal: return true
6565
default: return false
6666
}
6767
}
6868

6969
/// Returns `true` iff the receiver is `.int64`, `.double`, or `.decimal`.
70-
/// - Note: `.decimal` is only considered a number on platforms that have `NSDecimalNumber`.
70+
/// - Note: `.decimal` is only considered a number on platforms that have `Decimal`.
7171
/// On platforms where `.decimal` is a dummy value, it's not a treated as a number.
7272
var isNumber: Bool {
7373
switch self {
@@ -140,7 +140,7 @@ public extension JSON {
140140
/// When setting, replaces the receiver with the given integral value, or with
141141
/// null if the value is `nil`.
142142
///
143-
/// - Note: `.decimal` is only supported on platforms with `NSDecimalNumber`. On platforms without it,
143+
/// - Note: `.decimal` is only supported on platforms with `Decimal`. On platforms without it,
144144
/// the `.decimal` dummy value is not treated as a number.
145145
var int64: Int64? {
146146
get {
@@ -158,12 +158,13 @@ public extension JSON {
158158
/// Returns the integral value if the receiver is `.int64`, `.double`, or `.decimal`, otherwise `nil`.
159159
/// If the receiver is `.double`, the value is truncated. If it does not fit in an `Int`, `nil` is returned.
160160
/// If the receiver is `.int64` and the value does not fit in an `Int`, `nil` is returned.
161-
/// If the receiver is `.decimal`, and the value does not fit in an `Int`, `nil` is returned.
161+
/// If the receiver is `.decimal`, the value is returned using `NSDecimalNumber.int64Value`. If it does not
162+
/// fit in an `Int`, `nil` is returned.
162163
///
163164
/// When setting, replaces the receiver with the given integral value, or with
164165
/// null if the value is `nil`.
165166
///
166-
/// - Note: `.decimal` is only supported on platforms with `NSDecimalNumber`. On platforms without it,
167+
/// - Note: `.decimal` is only supported on platforms with `Decimal`. On platforms without it,
167168
/// the `.decimal` dummy value is not treated as a number.
168169
var int: Int? {
169170
get {
@@ -183,7 +184,7 @@ public extension JSON {
183184
/// When setting, replaces the receiver with the given double value, or with
184185
/// null if the value is `nil`.
185186
///
186-
/// - Note: `.decimal` is only supported on platforms with `NSDecimalNumber`. On platforms without it,
187+
/// - Note: `.decimal` is only supported on platforms with `Decimal`. On platforms without it,
187188
/// the `.decimal` dummy value is not treated as a number.
188189
var double: Double? {
189190
get {
@@ -192,7 +193,8 @@ public extension JSON {
192193
case .double(let d): return d
193194
case .decimal(let d):
194195
#if os(iOS) || os(OSX) || os(watchOS) || os(tvOS)
195-
return d.doubleValue
196+
// NB: Decimal does not have any accessor to produce a Double
197+
return NSDecimalNumber(decimal: d).doubleValue
196198
#else
197199
return nil
198200
#endif
@@ -241,7 +243,7 @@ public extension JSON {
241243
/// Returns the string value if the receiver is `.string`, coerces the value to a string if
242244
/// the receiver is `.bool`, `.null`, `.int64`, `.double`, or `.decimal, or otherwise returns `nil`.
243245
///
244-
/// - Note: `.decimal` is only supported on platforms with `NSDecimalNumber`. On platforms without it,
246+
/// - Note: `.decimal` is only supported on platforms with `Decimal`. On platforms without it,
245247
/// the `.decimal` dummy value returns `nil`.
246248
var asString: String? {
247249
return try? toString()
@@ -303,11 +305,12 @@ internal func convertDoubleToInt64(_ d: Double) -> Int64? {
303305
}
304306

305307
#if os(iOS) || os(OSX) || os(watchOS) || os(tvOS)
306-
internal func convertDecimalToInt64(_ d: NSDecimalNumber) -> Int64? {
307-
if d > Int64.maxDecimalNumber || d < Int64.minDecimalNumber {
308+
internal func convertDecimalToInt64(_ d: Decimal) -> Int64? {
309+
if d > Int64.maxDecimal || d < Int64.minDecimal {
308310
return nil
309311
}
310-
return d.int64Value
312+
// NB: Decimal does not have any appropriate accessor
313+
return NSDecimalNumber(decimal: d).int64Value
311314
}
312315
#else
313316
internal func convertDecimalToInt64(_ d: ()) -> Int64? {

0 commit comments

Comments
 (0)