Skip to content

Commit aec5170

Browse files
authored
Bin compat: NSDecimalString should accept dictionary in addition to locale (#769)
NSDecimalString historically accepted Any as the second parameter, which could be either a Locale or a Dictionary. We should keep that behavior.
1 parent 4956b8f commit aec5170

File tree

4 files changed

+34
-18
lines changed

4 files changed

+34
-18
lines changed

Sources/FoundationEssentials/Decimal/Decimal+Compatibility.swift

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,8 +409,24 @@ public func _NSDecimalCompact(_ number: UnsafeMutablePointer<Decimal>) {
409409
_ decimal: UnsafePointer<Decimal>,
410410
_ locale: Any? = nil
411411
) -> String {
412-
let useLocale = locale as? Locale
413-
return decimal.pointee._toString(with: useLocale)
412+
var decimalSeparator = "."
413+
if let useLocale = locale as? Locale,
414+
let separator = useLocale.decimalSeparator {
415+
decimalSeparator = separator
416+
}
417+
#if FOUNDATION_FRAMEWORK
418+
if let dictionary = locale as? [AnyHashable : Any] {
419+
// NSDecimal favored NSLocale.Key.decimalSeparator if
420+
// both keys are present.
421+
if let separator = dictionary["NSDecimalSeparator"] as? String {
422+
decimalSeparator = separator
423+
}
424+
if let separator = dictionary[NSLocale.Key.decimalSeparator.rawValue] as? String {
425+
decimalSeparator = separator
426+
}
427+
}
428+
#endif
429+
return decimal.pointee._toString(withDecimalSeparator: decimalSeparator)
414430
}
415431

416432
#if FOUNDATION_FRAMEWORK

Sources/FoundationEssentials/Decimal/Decimal+Conformances.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ extension Decimal : CustomStringConvertible {
2929
}
3030

3131
public var description: String {
32-
return self._toString()
32+
return self._toString(withDecimalSeparator: ".")
3333
}
3434
}
3535

Sources/FoundationEssentials/Decimal/Decimal.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,14 @@ extension Decimal {
187187
#else
188188
@_spi(SwiftCorelibsFoundation)
189189
public func toString(with locale: Locale? = nil) -> String {
190-
_toString(with: locale)
190+
let separator: String
191+
if let locale = locale,
192+
let localizedSeparator = locale.decimalSeparator {
193+
separator = localizedSeparator
194+
} else {
195+
separator = "."
196+
}
197+
return _toString(withDecimalSeparator: separator)
191198
}
192199

193200
@_spi(SwiftCorelibsFoundation)
@@ -199,21 +206,14 @@ extension Decimal {
199206
_decimal(from: stringView, decimalSeparator: decimalSeparator, matchEntireString: matchEntireString).asOptional
200207
}
201208
#endif
202-
internal func _toString(with locale: Locale? = nil) -> String {
209+
internal func _toString(withDecimalSeparator separator: String) -> String {
203210
if self.isNaN {
204211
return "NaN"
205212
}
206213
if self._length == 0 {
207214
return "0"
208215
}
209216
var buffer = ""
210-
let separator: String
211-
if let locale = locale,
212-
let localizedSeparator = locale.decimalSeparator {
213-
separator = String(localizedSeparator.reversed())
214-
} else {
215-
separator = "."
216-
}
217217
var copy = self
218218
while copy._exponent > 0 {
219219
buffer += "0"

Tests/FoundationEssentialsTests/DecimalTests.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,10 @@ final class DecimalTests : XCTestCase {
112112

113113
func test_DescriptionWithLocale() {
114114
let decimal = Decimal(string: "-123456.789")!
115-
XCTAssertEqual(decimal._toString(with: nil), "-123456.789")
116-
let en = decimal._toString(with: Locale(identifier: "en_GB"))
115+
XCTAssertEqual(decimal._toString(withDecimalSeparator: "."), "-123456.789")
116+
let en = decimal._toString(withDecimalSeparator: Locale(identifier: "en_GB").decimalSeparator!)
117117
XCTAssertEqual(en, "-123456.789")
118-
let fr = decimal._toString(with: Locale(identifier: "fr_FR"))
118+
let fr = decimal._toString(withDecimalSeparator: Locale(identifier: "fr_FR").decimalSeparator!)
119119
XCTAssertEqual(fr, "-123456,789")
120120
}
121121

@@ -1222,10 +1222,10 @@ final class DecimalTests : XCTestCase {
12221222
#else
12231223
func test_toString() {
12241224
let decimal = Decimal(string: "-123456.789")!
1225-
XCTAssertEqual(decimal.toString(with: nil), "-123456.789")
1226-
let en = decimal.toString(with: Locale(identifier: "en_GB"))
1225+
XCTAssertEqual(decimal._toString(withDecimalSeparator: "."), "-123456.789")
1226+
let en = decimal._toString(withDecimalSeparator: Locale(identifier: "en_GB").decimalSeparator!)
12271227
XCTAssertEqual(en, "-123456.789")
1228-
let fr = decimal.toString(with: Locale(identifier: "fr_FR"))
1228+
let fr = decimal._toString(withDecimalSeparator: Locale(identifier: "fr_FR").decimalSeparator!)
12291229
XCTAssertEqual(fr, "-123456,789")
12301230
}
12311231

0 commit comments

Comments
 (0)