From 7e22f43c81ba3eb99ccf368f95f3e5555826ae66 Mon Sep 17 00:00:00 2001 From: Pierre-Marie Padiou Date: Wed, 12 Feb 2025 11:09:37 +0100 Subject: [PATCH] Use a formatter to display `Btc`/`MilliBtc` amounts (#90) Display at most 8 decimals, instead of the default which may even use the exponent display occasionnally. --- .../acinq/bitcoin/scalacompat/BtcAmount.scala | 13 +++++++++--- .../bitcoin/scalacompat/BtcAmountSpec.scala | 21 +++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/main/scala/fr/acinq/bitcoin/scalacompat/BtcAmount.scala b/src/main/scala/fr/acinq/bitcoin/scalacompat/BtcAmount.scala index eb4bc095..885f07b4 100644 --- a/src/main/scala/fr/acinq/bitcoin/scalacompat/BtcAmount.scala +++ b/src/main/scala/fr/acinq/bitcoin/scalacompat/BtcAmount.scala @@ -1,5 +1,10 @@ package fr.acinq.bitcoin.scalacompat +import fr.acinq.bitcoin.scalacompat.BtcAmount.{btcFormat, milliBtcFormat} + +import java.text.{DecimalFormat, DecimalFormatSymbols} +import java.util.Locale + sealed trait BtcAmount case class Satoshi(private val underlying: Long) extends BtcAmount with Ordered[Satoshi] { @@ -52,7 +57,7 @@ case class MilliBtc(private val underlying: BigDecimal) extends BtcAmount with O def toBigDecimal: BigDecimal = underlying def toDouble: Double = underlying.toDouble def toLong: Long = underlying.toLong - override def toString = s"$underlying mBTC" + override def toString = s"${milliBtcFormat.format(underlying)} mBTC" // @formatter:on } @@ -82,7 +87,7 @@ case class Btc(private val underlying: BigDecimal) extends BtcAmount with Ordere def toBigDecimal: BigDecimal = underlying def toDouble: Double = underlying.toDouble def toLong: Long = underlying.toLong - override def toString = s"$underlying BTC" + override def toString = s"${btcFormat.format(underlying)} BTC" // @formatter:on } @@ -90,4 +95,6 @@ object BtcAmount { val Coin = 100000000L val Cent = 1000000L val MaxMoney: Double = 21e6 * Coin -} \ No newline at end of file + val milliBtcFormat = new DecimalFormat("#.#####", new DecimalFormatSymbols(Locale.US)) + val btcFormat = new DecimalFormat("#.########", new DecimalFormatSymbols(Locale.US)) +} diff --git a/src/test/scala/fr/acinq/bitcoin/scalacompat/BtcAmountSpec.scala b/src/test/scala/fr/acinq/bitcoin/scalacompat/BtcAmountSpec.scala index 45c2dbe5..14da8917 100644 --- a/src/test/scala/fr/acinq/bitcoin/scalacompat/BtcAmountSpec.scala +++ b/src/test/scala/fr/acinq/bitcoin/scalacompat/BtcAmountSpec.scala @@ -2,6 +2,8 @@ package fr.acinq.bitcoin.scalacompat import org.scalatest.FunSuite +import java.util.Locale + class BtcAmountSpec extends FunSuite { test("btc/millibtc/satoshi conversions") { @@ -94,4 +96,23 @@ class BtcAmountSpec extends FunSuite { assert((1.1 btc).min(90000000 sat) === Btc(0.9)) } + test("toString formatting") { + assert((0.00000000 btc).toString == "0 BTC") + assert((10.00000000 btc).toString == "10 BTC") + assert((1.23456789 btc).toString == "1.23456789 BTC") + assert((-1.23456789 btc).toString == "-1.23456789 BTC") + assert((1.2345 btc).toString == "1.2345 BTC") + assert((-1.2345 btc).toString == "-1.2345 BTC") + + assert((0 btc).toMilliBtc.toString == "0 mBTC") + assert((10.00000000 btc).toMilliBtc.toString == "10000 mBTC") + assert((1.23456789 btc).toMilliBtc.toString == "1234.56789 mBTC") + assert((-1.23456789 btc).toMilliBtc.toString == "-1234.56789 mBTC") + assert((1.2345 btc).toMilliBtc.toString == "1234.5 mBTC") + assert((-1.2345 btc).toMilliBtc.toString == "-1234.5 mBTC") + assert((1.234 btc).toMilliBtc.toString == "1234 mBTC") + assert((-1.234 btc).toMilliBtc.toString == "-1234 mBTC") + + } + }