Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve balance formatting #246

Merged
merged 3 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cli/src/component/normal/wallet/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use ratatui::{
layout::{Constraint, Direction, Layout, Rect},
widgets::{Padding, Row, Table},
};
use tari_launchpad_protocol::tari_format::TariFormat;

use crate::{
component::{elements::block_with_title, Component, ComponentEvent, Frame, Input, Pass},
Expand Down Expand Up @@ -112,7 +113,7 @@ impl<B: Backend> Component<B> for BalanceWidget {
}
}

fn rows<'a>(items: impl IntoIterator<Item = (&'a str, Option<u64>)>) -> Vec<Row<'a>> {
fn rows<'a>(items: impl IntoIterator<Item = (&'a str, Option<TariFormat>)>) -> Vec<Row<'a>> {
let mut rows = Vec::new();
for (title, value) in items {
let value = value
Expand Down
2 changes: 2 additions & 0 deletions libs/protocol/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ pub mod session;
pub mod settings;
pub mod wallet;

pub mod tari_format;

pub const ACTIONS: &str = "tari://actions";
pub const REACTIONS: &str = "tari://reactions";
83 changes: 83 additions & 0 deletions libs/protocol/src/tari_format.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2023. The Tari Project
// SPDX-License-Identifier: BSD-3-Clause

use std::{fmt, fmt::Display};

use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)]
#[serde(transparent)]
pub struct TariFormat {
value: u64,
}

impl TariFormat {
pub fn as_u64(&self) -> u64 {
self.value
}
}

impl From<u64> for TariFormat {
fn from(value: u64) -> Self {
Self { value }
}
}

impl Display for TariFormat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut value = self.value;
let unit = if value < 1_000_000 { "μT" } else { "T" };
let mut decimals = None;
if value >= 1_000_000 {
decimals = Some((value % 1_000_000).to_string());
value /= 1_000_000;
}
let val_str = value
.to_string()
.as_bytes()
.rchunks(3)
.rev()
.map(std::str::from_utf8)
.collect::<Result<Vec<&str>, _>>()
.unwrap()
.join(",");

let dec_str = match decimals {
Some(dec) => format!(".{:0<03.3}", dec),
None => String::new(),
};
write!(f, "{val_str}{dec_str} {unit}")
}
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn format_whole_number() {
let value = 1_234_567_891_000_000;
let tari = TariFormat::from(value);
assert_eq!(tari.to_string(), "1,234,567,891.000 T");
}

#[test]
fn format_small_number() {
let value = 123_456;
let tari = TariFormat::from(value);
assert_eq!(tari.to_string(), "123,456 μT");
}
#[test]
fn format_big_number_w_frac() {
let value = 1_234_567_890_222_333;
let tari = TariFormat::from(value);
assert_eq!(tari.to_string(), "1,234,567,890.222 T");
}

#[test]
fn format_zero() {
let value = 0;
let tari = TariFormat::from(value);
assert_eq!(tari.to_string(), "0 μT");
}
}
10 changes: 6 additions & 4 deletions libs/protocol/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ use std::collections::VecDeque;

use serde::{Deserialize, Serialize};

use crate::tari_format::TariFormat;

const HISTORY_LIMIT: usize = 30;

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -55,10 +57,10 @@ impl Default for WalletState {

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct WalletBalance {
pub available: u64,
pub pending_incoming: u64,
pub pending_outgoing: u64,
pub timelocked: u64,
pub available: TariFormat,
pub pending_incoming: TariFormat,
pub pending_outgoing: TariFormat,
pub timelocked: TariFormat,
}

impl WalletState {
Expand Down
8 changes: 4 additions & 4 deletions libs/sdm-launchpad/src/wallet_grpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,10 @@ impl WalletGrpcWorker {

fn process_balance(&mut self, response: GetBalanceResponse) -> Result<(), Error> {
let balance = WalletBalance {
available: response.available_balance,
pending_incoming: response.pending_incoming_balance,
pending_outgoing: response.pending_outgoing_balance,
timelocked: response.timelocked_balance,
available: response.available_balance.into(),
pending_incoming: response.pending_incoming_balance.into(),
pending_outgoing: response.pending_outgoing_balance.into(),
timelocked: response.timelocked_balance.into(),
};
let delta = WalletDelta::UpdateBalance(balance);
self.send_update(delta)
Expand Down
4 changes: 2 additions & 2 deletions libs/sdm-launchpad/tests/test_mining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ impl TestState {
.as_ref()
.and_then(|state| state.wallet.balance.as_ref());
if let Some(balance) = balance {
self.initial_funds = balance.available;
self.initial_funds = balance.available.as_u64();
true
} else {
false
Expand All @@ -155,7 +155,7 @@ impl TestState {
.state
.as_ref()
.and_then(|state| state.wallet.balance.as_ref())
.map(|balance| balance.available > self.initial_funds)
.map(|balance| balance.available.as_u64() > self.initial_funds)
.unwrap_or_default()
}
}
10 changes: 5 additions & 5 deletions libs/sim-launchpad/src/simulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,10 @@ impl Simulator {
self.apply_wallet_delta(delta)?;
if new_state {
let balance = WalletBalance {
available: 0,
pending_incoming: 0,
pending_outgoing: 0,
timelocked: 0,
available: 0.into(),
pending_incoming: 0.into(),
pending_outgoing: 0.into(),
timelocked: 0.into(),
};
let delta = WalletDelta::UpdateBalance(balance);
self.apply_wallet_delta(delta)?;
Expand All @@ -269,7 +269,7 @@ impl Simulator {
let session = self.lp_state.config.session.clone();
if session.is_miner_active() && self.mined_at.elapsed() >= Duration::from_secs(10) {
let mut balance = self.lp_state.wallet.balance.clone().unwrap_or_default();
balance.available += 1_000;
balance.available = (balance.available.as_u64() + 1_000).into();
let delta = WalletDelta::UpdateBalance(balance);
self.apply_wallet_delta(delta)?;
// TODO: Add a transaction
Expand Down