use std::fmt;
use std::str::FromStr;
const DECIMALS: usize = 8;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Amount(u64);
impl Amount {
pub const ZERO: Amount = Amount(0);
pub const ONE_WAVELET: Amount = Amount(1);
pub const ONE_WAVES: Amount = Amount(100_000_000);
pub fn from_wavelet(wavelet: u64) -> Amount {
Amount(wavelet)
}
pub fn max_value() -> Amount {
Amount(u64::max_value())
}
pub fn min_value() -> Amount {
Amount(u64::min_value())
}
pub fn as_wavelet(self) -> u64 {
self.0
}
pub fn as_waves(self) -> f64 {
let real = format!("{:0width$}", self.0, width = DECIMALS);
if real.len() == DECIMALS {
let result = format!("0.{}", &real[real.len() - DECIMALS..]);
f64::from_str(&result).unwrap()
} else {
let result = format!(
"{}.{}",
&real[0..(real.len() - DECIMALS)],
&real[real.len() - DECIMALS..]
);
f64::from_str(&result).unwrap()
}
}
}
impl Default for Amount {
fn default() -> Self {
Amount::ZERO
}
}
impl fmt::Display for Amount {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_waves())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
let wavelet = 1_000;
let balance = Amount::from_wavelet(wavelet);
assert_eq!(balance.as_waves(), 0.00001);
let wavelet = 1_000_000;
let balance = Amount::from_wavelet(wavelet);
assert_eq!(balance.as_waves(), 0.01);
let wavelet = 1_000_000_000;
let balance = Amount::from_wavelet(wavelet);
assert_eq!(balance.as_waves(), 10.0);
}
#[test]
fn test_one_waves() {
let one_waves = Amount::ONE_WAVES;
assert_eq!(one_waves.as_waves(), 1.0);
}
}