Skip to content

Commit

Permalink
fix: add display_currency_decimal method (tari-project#3445)
Browse files Browse the repository at this point in the history
Description
---
The inner type of `Tari` changed from `f64` to `decimal_rs::Decimal`.
Also, `display_currency` method was replaced with `format_currency` that adds separators to formatted strings.

Motivation and Context
---
`display_currency` method forces us to use `f64` that is not accurate for finance calculations.

How Has This Been Tested?
---
Updated unit tests.
**TODO:** Smoke test: run the wallet and the node.
  • Loading branch information
therustmonk authored Oct 14, 2021
1 parent 76bc1f0 commit 1f52ffc
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 83 deletions.
51 changes: 51 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion applications/tari_console_wallet/src/automation/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use super::error::CommandError;
use log::*;
use std::{
convert::TryFrom,
fs::File,
io::{LineWriter, Write},
str::FromStr,
Expand Down Expand Up @@ -661,7 +662,7 @@ pub async fn command_runner(
}
if count > 0 {
let average = f64::from(sum) / count as f64;
let average = Tari::from(average / 1_000_000f64);
let average = Tari::try_from(average / 1_000_000f64)?;
println!("Average value UTXO : {}", average);
}
if let Some(max) = values.iter().max() {
Expand Down
7 changes: 6 additions & 1 deletion applications/tari_console_wallet/src/automation/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ use std::num::{ParseFloatError, ParseIntError};
use chrono_english::DateError;
use log::*;
use tari_app_utilities::utilities::ExitCodes;
use tari_core::transactions::{tari_amount::MicroTariError, transaction::TransactionError};
use tari_core::transactions::{
tari_amount::{MicroTariError, TariConversionError},
transaction::TransactionError,
};
use tari_wallet::{
error::{WalletError, WalletStorageError},
output_manager_service::error::OutputManagerError,
Expand All @@ -41,6 +44,8 @@ pub const LOG_TARGET: &str = "wallet::automation::error";
pub enum CommandError {
#[error("Argument error - were they in the right order?")]
Argument,
#[error("Tari value conversion error `{0}`")]
TariConversionError(#[from] TariConversionError),
#[error("Transaction service error `{0}`")]
TransactionError(#[from] TransactionError),
#[error("Transaction service error `{0}`")]
Expand Down
2 changes: 2 additions & 0 deletions base_layer/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ sha3 = "0.9"
bytes = "0.5"
chrono = { version = "0.4.6", features = ["serde"] }
croaring = { version = "=0.4.5", optional = true }
decimal-rs = "0.1.20"
digest = "0.9.0"
futures = { version = "^0.3.16", features = ["async-await"] }
fs2 = "0.3.0"
Expand All @@ -64,6 +65,7 @@ num-format = "0.4.0"
tracing = "0.1.26"
tracing-futures = "*"
tracing-attributes = "*"
derive_more = "0.99.16"

[dev-dependencies]
tari_p2p = { version = "^0.11", path = "../../base_layer/p2p", features = ["test-mocks"] }
Expand Down
70 changes: 31 additions & 39 deletions base_layer/core/src/transactions/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

use std::sync::Arc;

use num::pow;
use rand::rngs::OsRng;
use tari_crypto::{
commitment::HomomorphicCommitmentFactory,
Expand Down Expand Up @@ -565,51 +564,44 @@ pub fn schema_to_transaction(txns: &[TransactionSchema]) -> (Vec<Arc<Transaction
/// # Examples
///
/// ```
/// use tari_core::transactions::helpers::display_currency;
/// assert_eq!(String::from("12,345.12"), display_currency(12345.12, 2, ","));
/// assert_eq!(String::from("12,345"), display_currency(12345.12, 0, ","));
/// use tari_core::transactions::helpers::format_currency;
/// assert_eq!("12,345.12", format_currency("12345.12", ','));
/// assert_eq!("12,345", format_currency("12345", ','));
/// ```
pub fn display_currency(value: f64, precision: usize, separator: &str) -> String {
let whole = value as usize;
let decimal = ((value - whole as f64) * pow(10_f64, precision)).round() as usize;
let formatted_whole_value = whole
.to_string()
.chars()
.rev()
.enumerate()
.fold(String::new(), |acc, (i, c)| {
if i != 0 && i % 3 == 0 {
format!("{}{}{}", acc, separator, c)
} else {
format!("{}{}", acc, c)
}
})
.chars()
.rev()
.collect::<String>();

if precision > 0 {
format!("{}.{:0>2$}", formatted_whole_value, decimal, precision)
} else {
formatted_whole_value
pub fn format_currency(value: &str, separator: char) -> String {
let full_len = value.len();
let mut buffer = String::with_capacity(full_len / 3 + full_len);
let mut iter = value.splitn(2, '.');
let whole = iter.next().unwrap_or("");
let mut idx = whole.len() as isize - 1;
for c in whole.chars() {
buffer.push(c);
if idx > 0 && idx % 3 == 0 {
buffer.push(separator);
}
idx -= 1;
}
if let Some(decimal) = iter.next() {
buffer.push('.');
buffer.push_str(decimal);
}
buffer
}

#[cfg(test)]
#[allow(clippy::excessive_precision)]
mod test {
use super::format_currency;

#[test]
fn display_currency() {
assert_eq!(String::from("0.00"), super::display_currency(0.0f64, 2, ","));
assert_eq!(String::from("0.000000000000"), super::display_currency(0.0f64, 12, ","));
assert_eq!(
String::from("123,456.123456789"),
super::display_currency(123_456.123_456_789_012_f64, 9, ",")
);
assert_eq!(
String::from("123,456"),
super::display_currency(123_456.123_456_789_012_f64, 0, ",")
);
assert_eq!(String::from("1,234"), super::display_currency(1234.1f64, 0, ","));
fn test_format_currency() {
assert_eq!("0.00", format_currency("0.00", ','));
assert_eq!("0.000000000000", format_currency("0.000000000000", ','));
assert_eq!("123,456.123456789", format_currency("123456.123456789", ','));
assert_eq!("123,456", format_currency("123456", ','));
assert_eq!("123", format_currency("123", ','));
assert_eq!("7,123", format_currency("7123", ','));
assert_eq!(".00", format_currency(".00", ','));
assert_eq!("00.", format_currency("00.", ','));
}
}
Loading

0 comments on commit 1f52ffc

Please sign in to comment.