Skip to content

Commit

Permalink
[ABW-2438] Parsing Decimals (#834)
Browse files Browse the repository at this point in the history
  • Loading branch information
kugel3 authored Oct 11, 2023
1 parent e36acd0 commit 31ccc63
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 10 deletions.
14 changes: 10 additions & 4 deletions Sources/EngineKit/RETDecimal+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,18 @@ extension RETDecimal {
// MARK: Truncation and rounding

extension RETDecimal {
/// Truncates to `decimalPlaces` decimals
public func truncated(decimalPlaces: UInt) -> RETDecimal {
/// Rounds to `decimalPlaces` decimals, in the direction of 0
public func floor(decimalPlaces: UInt) -> RETDecimal {
try! round(decimalPlaces: Int32(decimalPlaces), roundingMode: .toZero)
}

/// Rounds to `decimalPlaces` decimals, in the direction away from zero
public func ceil(decimalPlaces: UInt) -> RETDecimal {
try! round(decimalPlaces: Int32(decimalPlaces), roundingMode: .awayFromZero)
}

/// Rounds to `decimalPlaces` decimals
public func rounded(decimalPlaces: UInt) -> RETDecimal {
public func rounded(decimalPlaces: UInt = 0) -> RETDecimal {
try! round(decimalPlaces: Int32(decimalPlaces), roundingMode: .toNearestMidpointAwayFromZero)
}
}
Expand Down Expand Up @@ -130,7 +135,8 @@ extension RETDecimal {
formattedString: String,
locale: Locale = .autoupdatingCurrent
) throws {
var string = formattedString
// Pad with a leading zero, to make numbers with leading decimal separator parsable
var string = "0" + formattedString
// If the locale recognizes a grouping separator, we strip that from the string
if let groupingSeparator = locale.groupingSeparator {
string.replace(groupingSeparator, with: "")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public struct MinimumPercentageStepper: FeatureReducer {
var string: String

public init(value: RETDecimal) {
let clamped = value.rounded(decimalPlaces: 2).clamped
let clamped = value.clamped
self.value = clamped
self.string = clamped.formattedPlain()
}
Expand All @@ -34,13 +34,13 @@ public struct MinimumPercentageStepper: FeatureReducer {
public func reduce(into state: inout State, viewAction: ViewAction) -> Effect<Action> {
switch viewAction {
case .increaseTapped:
let value = state.value.map { $0 + percentageDelta } ?? 100
let value = state.value.map { $0.floor(decimalPlaces: 0) + percentageDelta } ?? 100
let clamped = value.clamped
state.value = clamped
state.string = clamped.formattedPlain()

case .decreaseTapped:
let value = state.value.map { $0 - percentageDelta } ?? 0
let value = state.value.map { $0.ceil(decimalPlaces: 0) - percentageDelta } ?? 0
let clamped = value.clamped
state.value = clamped
state.string = clamped.formattedPlain()
Expand All @@ -59,7 +59,7 @@ public struct MinimumPercentageStepper: FeatureReducer {
return .send(.delegate(.valueChanged))
}

private let percentageDelta: RETDecimal = 0.1
private let percentageDelta: RETDecimal = 1
}

extension MinimumPercentageStepper.State {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ public struct TransactionReviewGuarantee: Sendable, FeatureReducer {
}

let newMinimumDecimal = value * 0.01
let newAmount = newMinimumDecimal * state.details.amount
let divisibility = state.resource.divisibility.map(UInt.init) ?? RETDecimal.maxDivisibility
let newAmount = (newMinimumDecimal * state.details.amount).rounded(decimalPlaces: divisibility)
state.guarantee.amount = newAmount

return .none
Expand Down
4 changes: 3 additions & 1 deletion Tests/EngineKitTests/DecimalTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ final class DecimalTests: TestCase {
func doTest(_ decimalString: String, divisibility: UInt, expected expectedString: String, line: UInt = #line) throws {
let expected = try RETDecimal(value: expectedString)
let decimal = try RETDecimal(value: decimalString)
let actual = decimal.truncated(decimalPlaces: divisibility)
let actual = decimal.floor(decimalPlaces: divisibility)
XCTAssertEqual(actual, expected, line: line)
}

Expand Down Expand Up @@ -265,6 +265,8 @@ final class DecimalTests: TestCase {
}
let spanish = Locale(identifier: "es")
let us = Locale(identifier: "en_US_POSIX")
try doTest(",005", locale: spanish, expected: .init(value: "0.005"))
try doTest(".005", locale: us, expected: .init(value: "0.005"))
try doTest("1,001", locale: spanish, expected: .init(value: "1.001"))
try doTest("1,001", locale: us, expected: .init(value: "1001"))
try doTest("1.001,45", locale: spanish, expected: .init(value: "1001.45"))
Expand Down

0 comments on commit 31ccc63

Please sign in to comment.