solana_tokens/
token_display.rs1use {
2 solana_account_decoder::parse_token::real_number_string_trimmed,
3 solana_cli_output::display::build_balance_message,
4 std::{
5 fmt::{Debug, Display, Formatter, Result},
6 ops::Add,
7 },
8};
9
10const SOL_SYMBOL: &str = "◎";
11
12#[derive(PartialEq, Eq)]
13pub enum TokenType {
14 Sol,
15 SplToken,
16}
17
18pub struct Token {
19 amount: u64,
20 decimals: u8,
21 token_type: TokenType,
22}
23
24impl Token {
25 fn write_with_symbol(&self, f: &mut Formatter) -> Result {
26 match &self.token_type {
27 TokenType::Sol => {
28 let amount = build_balance_message(self.amount, false, false);
29 write!(f, "{SOL_SYMBOL}{amount}")
30 }
31 TokenType::SplToken => {
32 let amount = real_number_string_trimmed(self.amount, self.decimals);
33 write!(f, "{amount} tokens")
34 }
35 }
36 }
37
38 pub fn sol(amount: u64) -> Self {
39 Self {
40 amount,
41 decimals: 9,
42 token_type: TokenType::Sol,
43 }
44 }
45
46 pub fn spl_token(amount: u64, decimals: u8) -> Self {
47 Self {
48 amount,
49 decimals,
50 token_type: TokenType::SplToken,
51 }
52 }
53}
54
55impl Display for Token {
56 fn fmt(&self, f: &mut Formatter) -> Result {
57 self.write_with_symbol(f)
58 }
59}
60
61impl Debug for Token {
62 fn fmt(&self, f: &mut Formatter) -> Result {
63 self.write_with_symbol(f)
64 }
65}
66
67impl Add for Token {
68 type Output = Token;
69
70 fn add(self, other: Self) -> Self {
71 if self.token_type == other.token_type {
72 Self {
73 amount: self.amount + other.amount,
74 decimals: self.decimals,
75 token_type: self.token_type,
76 }
77 } else {
78 self
79 }
80 }
81}