From 2056e2638445f381d63631eb02403749ec91d6e6 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Fri, 18 Feb 2022 16:45:37 -0300 Subject: [PATCH] Adjust cli module to grpc.proto::volume field type change (string) --- .../main/java/bisq/cli/CurrencyFormat.java | 66 ++++++++++++------- .../table/builder/AbstractTableBuilder.java | 10 +-- .../cli/table/builder/OfferTableBuilder.java | 44 ++++++++----- .../bisq/cli/table/column/AltcoinColumn.java | 1 + .../bisq/cli/table/column/FiatColumn.java | 1 + 5 files changed, 76 insertions(+), 46 deletions(-) diff --git a/cli/src/main/java/bisq/cli/CurrencyFormat.java b/cli/src/main/java/bisq/cli/CurrencyFormat.java index ba0e84fca2..ba1029d3c7 100644 --- a/cli/src/main/java/bisq/cli/CurrencyFormat.java +++ b/cli/src/main/java/bisq/cli/CurrencyFormat.java @@ -39,8 +39,8 @@ public class CurrencyFormat { // Use the US locale for all DecimalFormat objects. private static final DecimalFormatSymbols DECIMAL_FORMAT_SYMBOLS = DecimalFormatSymbols.getInstance(Locale.US); - // Format numbers in US locale for CLI console. - private static final NumberFormat FRIENDLY_NUMBER_FORMAT = NumberFormat.getInstance(Locale.US); + // Format all numbers displayed in the CLI console with the US locale (no i18n support for CLI). + private static final NumberFormat US_LOCALE_NUMBER_FORMAT = NumberFormat.getInstance(Locale.US); // Formats numbers for internal use, i.e., grpc request parameters. private static final DecimalFormat INTERNAL_FIAT_DECIMAL_FORMAT = new DecimalFormat("##############0.0000"); @@ -54,6 +54,9 @@ public class CurrencyFormat { static final DecimalFormat BSQ_FORMAT = new DecimalFormat("###,###,###,##0.00", DECIMAL_FORMAT_SYMBOLS); static final DecimalFormat SEND_BSQ_FORMAT = new DecimalFormat("###########0.00", DECIMAL_FORMAT_SYMBOLS); + static final DecimalFormat ALTCOIN_VOLUME_FORMAT = new DecimalFormat("########0.00", DECIMAL_FORMAT_SYMBOLS); + static final DecimalFormat FIAT_VOLUME_FORMAT = new DecimalFormat("###########0", DECIMAL_FORMAT_SYMBOLS); + static final BigDecimal SECURITY_DEPOSIT_MULTIPLICAND = new BigDecimal("0.01"); @SuppressWarnings("BigDecimalMethodWithoutRoundingCalled") @@ -71,13 +74,28 @@ public class CurrencyFormat { return BSQ_FORMAT.format(BigDecimal.valueOf(sats).divide(BSQ_SATOSHI_DIVISOR)); } + @Deprecated // TODO delete public static String formatBsqAmount(long bsqSats) { - FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(2); - FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(2); - FRIENDLY_NUMBER_FORMAT.setRoundingMode(HALF_UP); + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(2); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(2); + US_LOCALE_NUMBER_FORMAT.setRoundingMode(HALF_UP); return SEND_BSQ_FORMAT.format((double) bsqSats / SATOSHI_DIVISOR.doubleValue()); } + public static String formatVolumeString(String volumeString, int precision) { + if (volumeString == null || volumeString.isBlank()) + return ""; + + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(precision); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(precision); + US_LOCALE_NUMBER_FORMAT.setRoundingMode(HALF_UP); + var volAsDouble = new BigDecimal(volumeString).doubleValue(); + if (precision == 0) + return FIAT_VOLUME_FORMAT.format(volAsDouble); + else + return ALTCOIN_VOLUME_FORMAT.format(volAsDouble); + } + public static String formatTxFeeRateInfo(TxFeeRateInfo txFeeRateInfo) { if (txFeeRateInfo.getUseCustomTxFeeRate()) return format("custom tx fee rate: %s sats/byte, network rate: %s sats/byte, min network rate: %s sats/byte", @@ -118,31 +136,31 @@ public class CurrencyFormat { } public static String formatInternalFiatPrice(double price) { - FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(4); - FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(4); - return FRIENDLY_NUMBER_FORMAT.format(price); + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(4); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(4); + return US_LOCALE_NUMBER_FORMAT.format(price); } @Deprecated public static String formatPrice(long price) { - FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(4); - FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(4); - FRIENDLY_NUMBER_FORMAT.setRoundingMode(UNNECESSARY); - return FRIENDLY_NUMBER_FORMAT.format((double) price / 10_000); + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(4); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(4); + US_LOCALE_NUMBER_FORMAT.setRoundingMode(UNNECESSARY); + return US_LOCALE_NUMBER_FORMAT.format((double) price / 10_000); } public static String formatCryptoCurrencyPrice(long price) { - FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(8); - FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(8); - FRIENDLY_NUMBER_FORMAT.setRoundingMode(UNNECESSARY); - return FRIENDLY_NUMBER_FORMAT.format((double) price / SATOSHI_DIVISOR.doubleValue()); + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(8); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(8); + US_LOCALE_NUMBER_FORMAT.setRoundingMode(UNNECESSARY); + return US_LOCALE_NUMBER_FORMAT.format((double) price / SATOSHI_DIVISOR.doubleValue()); } public static String formatFiatVolume(long volume) { - FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(0); - FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(0); - FRIENDLY_NUMBER_FORMAT.setRoundingMode(HALF_UP); - return FRIENDLY_NUMBER_FORMAT.format((double) volume / 10_000); + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(0); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(0); + US_LOCALE_NUMBER_FORMAT.setRoundingMode(HALF_UP); + return US_LOCALE_NUMBER_FORMAT.format((double) volume / 10_000); } public static String formatCryptoCurrencyVolume(long volume) { @@ -151,10 +169,10 @@ public class CurrencyFormat { } public static String formatCryptoCurrencyVolume(long volume, int precision) { - FRIENDLY_NUMBER_FORMAT.setMinimumFractionDigits(precision); - FRIENDLY_NUMBER_FORMAT.setMaximumFractionDigits(precision); - FRIENDLY_NUMBER_FORMAT.setRoundingMode(HALF_UP); - return FRIENDLY_NUMBER_FORMAT.format((double) volume / SATOSHI_DIVISOR.doubleValue()); + US_LOCALE_NUMBER_FORMAT.setMinimumFractionDigits(precision); + US_LOCALE_NUMBER_FORMAT.setMaximumFractionDigits(precision); + US_LOCALE_NUMBER_FORMAT.setRoundingMode(HALF_UP); + return US_LOCALE_NUMBER_FORMAT.format((double) volume / SATOSHI_DIVISOR.doubleValue()); } @Deprecated diff --git a/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java b/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java index cdb5f3ffa3..1b57fa691c 100644 --- a/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/AbstractTableBuilder.java @@ -20,7 +20,6 @@ package bisq.cli.table.builder; import bisq.proto.grpc.OfferInfo; import java.util.List; -import java.util.function.Function; import java.util.function.Predicate; @@ -32,7 +31,7 @@ import bisq.cli.table.Table; */ abstract class AbstractTableBuilder { - protected final Function toBlankOrNonZeroValue = (s) -> s.trim().equals("0") ? "" : s; + protected final Predicate isFiatOffer = (o) -> o.getBaseCurrencyCode().equals("BTC"); protected final TableType tableType; protected final List protos; @@ -45,6 +44,9 @@ abstract class AbstractTableBuilder { } public abstract Table build(); - - protected final Predicate isFiatOffer = (o) -> o.getBaseCurrencyCode().equals("BTC"); } + +/* + var currencyCode = isFiatOffer.test(o); + + */ diff --git a/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java b/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java index a97c73b848..5a86ce92a7 100644 --- a/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java +++ b/cli/src/main/java/bisq/cli/table/builder/OfferTableBuilder.java @@ -26,13 +26,12 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; +import static bisq.cli.CurrencyFormat.formatVolumeString; import static bisq.cli.table.builder.TableBuilderConstants.*; import static bisq.cli.table.builder.TableType.OFFER_TBL; -import static bisq.cli.table.column.AltcoinColumn.DISPLAY_MODE.ALTCOIN_OFFER_VOLUME; import static bisq.cli.table.column.Column.JUSTIFICATION.LEFT; import static bisq.cli.table.column.Column.JUSTIFICATION.NONE; import static bisq.cli.table.column.Column.JUSTIFICATION.RIGHT; -import static bisq.cli.table.column.FiatColumn.DISPLAY_MODE.VOLUME; import static bisq.cli.table.column.ZippedStringColumns.DUPLICATION_MODE.EXCLUDE_DUPLICATES; import static java.lang.String.format; import static protobuf.OfferDirection.BUY; @@ -41,9 +40,7 @@ import static protobuf.OfferDirection.SELL; import bisq.cli.table.Table; -import bisq.cli.table.column.AltcoinColumn; import bisq.cli.table.column.Column; -import bisq.cli.table.column.FiatColumn; import bisq.cli.table.column.Iso8601DateTimeColumn; import bisq.cli.table.column.SatoshiColumn; import bisq.cli.table.column.StringColumn; @@ -79,8 +76,8 @@ class OfferTableBuilder extends AbstractTableBuilder { @Nullable Column colEnabled = enabledColumn.get(); // Not boolean: YES, NO, or PENDING Column colFiatPrice = new StringColumn(format(COL_HEADER_DETAILED_PRICE, fiatTradeCurrency.get()), RIGHT); - Column colFiatVolume = new FiatColumn(format("Temp Volume (%s)", fiatTradeCurrency.get()), NONE, VOLUME); - Column colMinFiatVolume = new FiatColumn(format("Temp Min Volume (%s)", fiatTradeCurrency.get()), NONE, VOLUME); + Column colFiatVolume = new StringColumn(format("Temp Volume (%s)", fiatTradeCurrency.get()), NONE); + Column colMinFiatVolume = new StringColumn(format("Temp Min Volume (%s)", fiatTradeCurrency.get()), NONE); @Nullable Column colTriggerPrice = fiatTriggerPriceColumn.get(); @@ -95,8 +92,10 @@ class OfferTableBuilder extends AbstractTableBuilder { colFiatPrice.addRow(o.getPrice()); colMinAmount.addRow(o.getMinAmount()); colAmount.addRow(o.getAmount()); - colMinFiatVolume.addRow(o.getMinVolume()); - colFiatVolume.addRow(o.getVolume()); + + var volumePrecision = toOfferVolumePrecision.apply(o); + colMinFiatVolume.addRow(formatVolumeString(toBlankOrNonZeroValue.apply(o.getMinVolume()), volumePrecision)); + colFiatVolume.addRow(formatVolumeString(o.getVolume(), volumePrecision)); if (colTriggerPrice != null) colTriggerPrice.addRow(toBlankOrNonZeroValue.apply(o.getTriggerPrice())); @@ -142,12 +141,8 @@ class OfferTableBuilder extends AbstractTableBuilder { @Nullable Column colEnabled = enabledColumn.get(); // Not boolean: YES, NO, or PENDING Column colBtcPrice = new StringColumn(format(COL_HEADER_DETAILED_PRICE_OF_ALTCOIN, altcoinTradeCurrency.get()), RIGHT); - Column colBtcVolume = new AltcoinColumn(format("Temp Volume (%s)", altcoinTradeCurrency.get()), - NONE, - ALTCOIN_OFFER_VOLUME); - Column colMinBtcVolume = new AltcoinColumn(format("Temp Min Volume (%s)", altcoinTradeCurrency.get()), - NONE, - ALTCOIN_OFFER_VOLUME); + Column colBtcVolume = new StringColumn(format("Temp Volume (%s)", altcoinTradeCurrency.get()), NONE); + Column colMinBtcVolume = new StringColumn(format("Temp Min Volume (%s)", altcoinTradeCurrency.get()), NONE); @Nullable Column colTriggerPrice = altcoinTriggerPriceColumn.get(); @@ -162,8 +157,9 @@ class OfferTableBuilder extends AbstractTableBuilder { colBtcPrice.addRow(o.getPrice()); colAmount.addRow(o.getAmount()); colMinAmount.addRow(o.getMinAmount()); - colBtcVolume.addRow(o.getMinVolume()); - colMinBtcVolume.addRow(o.getVolume()); + var volumePrecision = toOfferVolumePrecision.apply(o); + colBtcVolume.addRow(formatVolumeString(o.getVolume(), volumePrecision)); + colMinBtcVolume.addRow(formatVolumeString(toBlankOrNonZeroValue.apply(o.getMinVolume()), volumePrecision)); if (colTriggerPrice != null) colTriggerPrice.addRow(toBlankOrNonZeroValue.apply(o.getTriggerPrice())); @@ -178,8 +174,8 @@ class OfferTableBuilder extends AbstractTableBuilder { new ZippedStringColumns(format(COL_HEADER_VOLUME_RANGE, altcoinTradeCurrency.get()), RIGHT, " - ", - colBtcVolume.asStringColumn(), - colMinBtcVolume.asStringColumn()); + colMinBtcVolume.asStringColumn(), + colBtcVolume.asStringColumn()); // Define and return the table instance with populated columns. @@ -215,6 +211,18 @@ class OfferTableBuilder extends AbstractTableBuilder { } } + // TODO Might want to move these three functions into superclass (if TradeTableBuilder needs them). + private final Function toBlankOrNonZeroValue = (s) -> s.trim().equals("0") ? "" : s; + private final Function toOfferCurrencyCode = (o) -> isFiatOffer.test(o) + ? o.getCounterCurrencyCode() + : o.getBaseCurrencyCode(); + private final Function toOfferVolumePrecision = (o) -> { + if (isFiatOffer.test(o)) + return 0; + else + return toOfferCurrencyCode.apply(o).equals("BSQ") ? 2 : 8; + }; + private final Supplier firstOfferInList = () -> (OfferInfo) protos.get(0); private final Supplier isShowingMyOffers = () -> firstOfferInList.get().getIsMyOffer(); private final Supplier isShowingFiatOffers = () -> isFiatOffer.test(firstOfferInList.get()); diff --git a/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java b/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java index 3b13171f7f..79f4976bf5 100644 --- a/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java +++ b/cli/src/main/java/bisq/cli/table/column/AltcoinColumn.java @@ -32,6 +32,7 @@ import static bisq.cli.table.column.Column.JUSTIFICATION.RIGHT; public class AltcoinColumn extends LongColumn { public enum DISPLAY_MODE { + @Deprecated ALTCOIN_OFFER_VOLUME, ALTCOIN_PRICE, @Deprecated diff --git a/cli/src/main/java/bisq/cli/table/column/FiatColumn.java b/cli/src/main/java/bisq/cli/table/column/FiatColumn.java index 9adb9de5a0..81ebcb7fe5 100644 --- a/cli/src/main/java/bisq/cli/table/column/FiatColumn.java +++ b/cli/src/main/java/bisq/cli/table/column/FiatColumn.java @@ -35,6 +35,7 @@ public class FiatColumn extends LongColumn { PRICE, @Deprecated TRIGGER_PRICE, + @Deprecated VOLUME }