gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]