[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-ios] 09/11: DD51 - CurrencySpecification
From: |
gnunet |
Subject: |
[taler-taler-ios] 09/11: DD51 - CurrencySpecification |
Date: |
Tue, 24 Oct 2023 22:45:25 +0200 |
This is an automated email from the git hooks/post-receive script.
marc-stibane pushed a commit to branch master
in repository taler-ios.
commit 7efecc640d3418f65aea51c8b93135283e10c7fd
Author: Marc Stibane <marc@taler.net>
AuthorDate: Tue Oct 24 22:37:28 2023 +0200
DD51 - CurrencySpecification
---
TalerWallet1/Helper/CurrencySpecification.swift | 119 ++++++++++++++----------
1 file changed, 72 insertions(+), 47 deletions(-)
diff --git a/TalerWallet1/Helper/CurrencySpecification.swift
b/TalerWallet1/Helper/CurrencySpecification.swift
index 6b8a059..cbbefc1 100644
--- a/TalerWallet1/Helper/CurrencySpecification.swift
+++ b/TalerWallet1/Helper/CurrencySpecification.swift
@@ -10,53 +10,78 @@ public struct CurrencyInfo {
let specs: CurrencySpecification
let formatter: CurrencyFormatter
- func string(for value: Double, useSymbol: Bool = true) -> String {
+ /// returns all characters left from the decimalSeparator
+ func integerPartStr(_ integerStr: String, decimalSeparator: String) ->
String {
+ if let integerIndex = integerStr.endIndex(of: decimalSeparator) {
+ // decimalSeparator was found ==> return all characters left of it
+ return String(integerStr[..<integerIndex])
+ }
+ guard let firstChar = integerStr.first else { return "" } // TODO:
should NEVER happen! Show error
+ let digitSet = CharacterSet.decimalDigits
+ if digitSet.contains(firstChar) {
+ // Currency Symbol is after the amount ==> return only the digits
+ return String(integerStr.unicodeScalars.filter {
digitSet.contains($0) })
+ } else {
+ // Currency Symbol is in front of the amount ==> return everything
+ return integerStr
+ }
+ }
+
+ func string(for valueTuple: (Double, Double), useSymbol: Bool = true) ->
String {
formatter.setUseSymbol(useSymbol)
- if let valueStr = formatter.string(for: value) {
- let decimalSeparator = formatter.decimalSeparator ??
specs.decimalSeparator
- if let decimalIndex = valueStr.endIndex(of: decimalSeparator) {
- var fraction = 1
- var integerStr = String(valueStr[..<decimalIndex])
- let fractionStr = valueStr[decimalIndex...]
- for character in fractionStr {
- let charStr = String(character)
- if let digit = Int(charStr) {
- let digitStr = fraction > specs.fractionalNormalDigits
?
- SuperScriptDigits(charStr)
: charStr
- integerStr += digitStr
- } else { integerStr += charStr }
- fraction += 1
+ let (integer, fraction) = valueTuple
+ if let integerStr = formatter.string(for: integer) {
+ if fraction == 0 { return integerStr } // TODO: add
trailing zeroes
+ if let fractionStr = formatter.string(for: fraction) {
+ if let decimalSeparator = formatter.currencyDecimalSeparator {
+ if let fractionIndex = fractionStr.endIndex(of:
decimalSeparator) {
+ var fractionPartStr =
String(fractionStr[fractionIndex...])
+ var resultStr = integerPartStr(integerStr,
decimalSeparator: decimalSeparator)
+ if !resultStr.contains(decimalSeparator) {
+ resultStr += decimalSeparator
+ }
+// print(resultStr, fractionPartStr)
+ var fractionCnt = 1
+ for character in fractionPartStr {
+ let isSuper = fractionCnt >
specs.fractionalNormalDigits
+ let charStr = String(character)
+ if let digit = Int(charStr) {
+ let digitStr = isSuper ?
SuperScriptDigits(charStr) : charStr
+ resultStr += digitStr
+ if (fractionCnt > 0) { fractionCnt += 1 }
+ } else {
+ // probably the Currency Code or Symbol. Just
pass it on...
+ resultStr += charStr
+ // make sure any following digits (part of the
currency name) are not converted to SuperScript
+ fractionCnt = 0
+ }
+ }
+// print(resultStr)
+ return resultStr
+ }
+ // if we arrive here then fractionStr doesn't have a
decimal separator. Yikes!
}
- return integerStr
+ // if we arrive here then the formatter doesn't have a
currencyDecimalSeparator
}
- return valueStr
- } else { // formatter doesn't work - we need to format ourselves
- var madeUpStr = ""
- var currencyName = scope.currency
- var hasSymbol = false
- if useSymbol && formatter.hasAltUnitName0 {
+ // if we arrive here then we do not get a formatted string for
fractionStr. Yikes!
+ }
+ // if we arrive here then we do not get a formatted string for
integerStr. Yikes!
+ // TODO: log.error(formatter doesn't work)
+ // we need to format ourselves
+ var currencyName = scope.currency
+ if useSymbol {
+ if formatter.hasAltUnitName0 {
if let symbol = specs.altUnitNames?[0] {
currencyName = symbol
- hasSymbol = true
}
}
- if specs.isCurrencyNameLeading {
- madeUpStr = currencyName
- if !hasSymbol {
- madeUpStr += " "
- }
- }
- let integerPart = Int(value)
- madeUpStr += String(integerPart)
- madeUpStr += specs.decimalSeparator
- if !specs.isCurrencyNameLeading {
- if !hasSymbol {
- madeUpStr += " "
- }
- madeUpStr += currencyName
- }
- return madeUpStr
- } // DIY
+ }
+ var madeUpStr = currencyName + " " + String(integer)
+// let homeCurrency = Locale.current.currency //'currency' is only
available in iOS 16 or newer
+ madeUpStr += Locale.current.decimalSeparator ?? "." //
currencyDecimalSeparator
+ madeUpStr += String(String(fraction).dropFirst()) // remove the
leading 0
+ // TODO: fractionalNormalDigits, fractionalTrailingZeroDigits
+ return madeUpStr
}
}
@@ -67,20 +92,20 @@ public struct CurrencySpecification2: Codable, Sendable {
public struct CurrencySpecification: Codable, Sendable {
enum CodingKeys: String, CodingKey {
case name = "name"
- case decimalSeparator = "decimal_separator"
- case groupSeparator = "group_separator"
+// case decimalSeparator = "decimal_separator"
+// case groupSeparator = "group_separator"
case fractionalInputDigits = "num_fractional_input_digits"
case fractionalNormalDigits = "num_fractional_normal_digits"
case fractionalTrailingZeroDigits =
"num_fractional_trailing_zero_digits"
- case isCurrencyNameLeading = "is_currency_name_leading"
+// case isCurrencyNameLeading = "is_currency_name_leading"
case altUnitNames = "alt_unit_names"
}
/// some name for this CurrencySpecification
let name: String
/// e.g. “.” for $, and “,” for €
- let decimalSeparator: String
- /// e.g. “,” for $, and “.” or “ ” for € (France uses a narrow space
character)
- let groupSeparator: String?
+// let decimalSeparator: String taken from Locale.current
+ /// e.g. “,” for $, and “.” or “ ” for € (France uses a narrow space
character, Hungaria a normal one)
+// let groupSeparator: String? taken from Locale.current
/// how much digits the user may enter after the decimal separator
let fractionalInputDigits: Int
/// €,$,£: 2; some arabic currencies: 3, ¥: 0
@@ -88,7 +113,7 @@ public struct CurrencySpecification: Codable, Sendable {
/// usually same as numFractionalNormalDigits, but e.g. might be 2 for ¥
let fractionalTrailingZeroDigits: Int
/// true for “$ 3.50”; false for “3,50 €”
- let isCurrencyNameLeading: Bool
+// let isCurrencyNameLeading: Bool
/// map of powers of 10 to alternative currency names / symbols
/// must always have an entry under "0" that defines the base name
/// e.g. "0 => €" or "3 => k€". For BTC, would be "0 => BTC, -3 => mBTC".
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-taler-ios] branch master updated (a0c6bdb -> bf7f8e3), gnunet, 2023/10/24
- [taler-taler-ios] 01/11: Assets cleanup, gnunet, 2023/10/24
- [taler-taler-ios] 02/11: Native Logging for wallet-core (QuickJS), gnunet, 2023/10/24
- [taler-taler-ios] 03/11: Logger, gnunet, 2023/10/24
- [taler-taler-ios] 05/11: Only call DetailsForAmount if non-zero, gnunet, 2023/10/24
- [taler-taler-ios] 10/11: CharacterSet+contains, gnunet, 2023/10/24
- [taler-taler-ios] 11/11: Layout for Pending - wip, gnunet, 2023/10/24
- [taler-taler-ios] 04/11: ExchangeRowView, gnunet, 2023/10/24
- [taler-taler-ios] 08/11: Cleanup, gnunet, 2023/10/24
- [taler-taler-ios] 09/11: DD51 - CurrencySpecification,
gnunet <=
- [taler-taler-ios] 07/11: intValue, fracValue, valueAsTuple, gnunet, 2023/10/24
- [taler-taler-ios] 06/11: Fix for NavigationView popping back, gnunet, 2023/10/24