trezoa_native_token/
lib.rs

1//! Definitions for the native TRZ token and its fractional lamports.
2
3#![allow(clippy::arithmetic_side_effects)]
4
5/// There are 10^9 lamports in one TRZ
6pub const LAMPORTS_PER_TRZ: u64 = 1_000_000_000;
7const TRZ_DECIMALS: usize = 9;
8
9/// Convert native tokens (TRZ) into fractional native tokens (lamports)
10pub fn trz_str_to_lamports(trz_str: &str) -> Option<u64> {
11    if trz_str == "." {
12        None
13    } else {
14        let (trz, lamports) = trz_str.split_once('.').unwrap_or((trz_str, ""));
15        let trz = if trz.is_empty() {
16            0
17        } else {
18            trz.parse::<u64>().ok()?
19        };
20        let lamports = if lamports.is_empty() {
21            0
22        } else {
23            format!("{lamports:0<9}")[..TRZ_DECIMALS].parse().ok()?
24        };
25        LAMPORTS_PER_TRZ
26            .checked_mul(trz)
27            .and_then(|x| x.checked_add(lamports))
28    }
29}
30
31use std::fmt::{Debug, Display, Formatter, Result};
32pub struct Trz(pub u64);
33
34impl Trz {
35    fn write_in_trz(&self, f: &mut Formatter) -> Result {
36        write!(
37            f,
38            "◎{}.{:09}",
39            self.0 / LAMPORTS_PER_TRZ,
40            self.0 % LAMPORTS_PER_TRZ
41        )
42    }
43}
44
45impl Display for Trz {
46    fn fmt(&self, f: &mut Formatter) -> Result {
47        self.write_in_trz(f)
48    }
49}
50
51impl Debug for Trz {
52    fn fmt(&self, f: &mut Formatter) -> Result {
53        self.write_in_trz(f)
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn test_trz_str_to_lamports() {
63        assert_eq!(0, trz_str_to_lamports("0.0").unwrap());
64        assert_eq!(1, trz_str_to_lamports("0.000000001").unwrap());
65        assert_eq!(10, trz_str_to_lamports("0.00000001").unwrap());
66        assert_eq!(100, trz_str_to_lamports("0.0000001").unwrap());
67        assert_eq!(1000, trz_str_to_lamports("0.000001").unwrap());
68        assert_eq!(10000, trz_str_to_lamports("0.00001").unwrap());
69        assert_eq!(100000, trz_str_to_lamports("0.0001").unwrap());
70        assert_eq!(1000000, trz_str_to_lamports("0.001").unwrap());
71        assert_eq!(10000000, trz_str_to_lamports("0.01").unwrap());
72        assert_eq!(100000000, trz_str_to_lamports("0.1").unwrap());
73        assert_eq!(1000000000, trz_str_to_lamports("1").unwrap());
74        assert_eq!(4_100_000_000, trz_str_to_lamports("4.1").unwrap());
75        assert_eq!(8_200_000_000, trz_str_to_lamports("8.2").unwrap());
76        assert_eq!(8_502_282_880, trz_str_to_lamports("8.50228288").unwrap());
77
78        assert_eq!(
79            u64::MAX,
80            trz_str_to_lamports("18446744073.709551615").unwrap()
81        );
82        // bigger than u64::MAX, error
83        assert_eq!(None, trz_str_to_lamports("18446744073.709551616"));
84        // Negative, error
85        assert_eq!(None, trz_str_to_lamports("-0.000000001"));
86        // i64::MIN as string, error
87        assert_eq!(None, trz_str_to_lamports("-9223372036.854775808"));
88    }
89}