From da5049627131aa24d6b922c64cb9dd68bef37821 Mon Sep 17 00:00:00 2001 From: Oscar Mira Date: Sun, 3 Mar 2024 12:43:47 +0100 Subject: [PATCH] lib: improve amount parsing and formating --- .../kotlin/im/molly/monero/MoneroAmount.kt | 4 ++++ .../kotlin/im/molly/monero/MoneroCurrency.kt | 24 +++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/android/src/main/kotlin/im/molly/monero/MoneroAmount.kt b/lib/android/src/main/kotlin/im/molly/monero/MoneroAmount.kt index 4d6267b..445a805 100644 --- a/lib/android/src/main/kotlin/im/molly/monero/MoneroAmount.kt +++ b/lib/android/src/main/kotlin/im/molly/monero/MoneroAmount.kt @@ -18,6 +18,8 @@ value class MoneroAmount(val atomicUnits: Long) : Parcelable { val xmr: BigDecimal get() = BigDecimal.valueOf(atomicUnits, ATOMIC_UNIT_SCALE) + val isZero: Boolean get() = atomicUnits == 0L + override fun toString() = atomicUnits.toString() operator fun plus(other: MoneroAmount) = @@ -39,6 +41,8 @@ inline val BigDecimal.xmr: MoneroAmount return MoneroAmount(atomicUnits) } +inline val Number.xmr: MoneroAmount get() = (this as BigDecimal).xmr + inline val Double.xmr: MoneroAmount get() = BigDecimal(this).xmr inline val Long.xmr: MoneroAmount get() = BigDecimal(this).xmr diff --git a/lib/android/src/main/kotlin/im/molly/monero/MoneroCurrency.kt b/lib/android/src/main/kotlin/im/molly/monero/MoneroCurrency.kt index 442bfac..eacdd36 100644 --- a/lib/android/src/main/kotlin/im/molly/monero/MoneroCurrency.kt +++ b/lib/android/src/main/kotlin/im/molly/monero/MoneroCurrency.kt @@ -1,5 +1,6 @@ package im.molly.monero +import java.text.DecimalFormat import java.text.NumberFormat import java.util.Locale import kotlin.math.absoluteValue @@ -19,16 +20,20 @@ object MoneroCurrency { } } - private val numberFormat = NumberFormat.getInstance(locale).apply { + private val numberFormat = (DecimalFormat.getInstance(locale) as DecimalFormat).apply { minimumFractionDigits = precision + isParseBigDecimal = true } open fun format(amount: MoneroAmount): String { return numberFormat.format(amount.xmr) } + /** + * @throw ParseException + */ open fun parse(source: String): MoneroAmount { - TODO() + return numberFormat.parse(source)?.xmr ?: MoneroAmount.ZERO } } @@ -59,7 +64,18 @@ object MoneroCurrency { return outputFormat.format(amount) } - fun format(amount: MoneroAmount, precision: Int): String { - return Format(precision = precision).format(amount) + fun format(amount: MoneroAmount, precision: Int, appendSymbol: Boolean = false): String { + val formatted = Format(precision = precision).format(amount) + return if (appendSymbol) "$formatted $SYMBOL" else formatted + } + + /** + * @throw ParseException + */ + fun parse(source: String, outputFormat: Format = ExactFormat): MoneroAmount { + return outputFormat.parse(source) } } + +fun MoneroAmount.toFormattedString(precision: Int = 5, appendSymbol: Boolean = false): String = + MoneroCurrency.format(amount = this, precision = precision, appendSymbol = appendSymbol)