1use cosmwasm_schema::cw_serde;
2use cosmwasm_std::Coin;
3
4use std::{fmt, fmt::Display};
5
6use cw_utils::NativeBalance;
7
8use crate::Cw20CoinVerified;
9
10#[cw_serde]
11
12pub enum Balance {
13 Native(NativeBalance),
14 Cw20(Cw20CoinVerified),
15}
16
17impl Default for Balance {
18 fn default() -> Balance {
19 Balance::Native(NativeBalance(vec![]))
20 }
21}
22
23impl Display for Balance {
24 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25 match self {
26 Balance::Native(native) => write!(f, "{native}"),
27 Balance::Cw20(cw20) => write!(f, "{cw20}"),
28 }?;
29 Ok(())
30 }
31}
32
33impl Balance {
34 pub fn is_empty(&self) -> bool {
35 match self {
36 Balance::Native(balance) => balance.is_empty(),
37 Balance::Cw20(coin) => coin.is_empty(),
38 }
39 }
40
41 pub fn normalize(&mut self) {
43 match self {
44 Balance::Native(balance) => balance.normalize(),
45 Balance::Cw20(_) => {}
46 }
47 }
48}
49
50impl From<Vec<Coin>> for Balance {
51 fn from(coins: Vec<Coin>) -> Balance {
52 Balance::Native(NativeBalance(coins))
53 }
54}
55
56impl From<Cw20CoinVerified> for Balance {
57 fn from(cw20_coin: Cw20CoinVerified) -> Balance {
58 Balance::Cw20(cw20_coin)
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use cosmwasm_std::{Addr, Uint128};
66
67 #[test]
68 fn default_balance_is_native() {
69 let balance: Balance = Default::default();
70 assert!(matches!(balance, Balance::Native(_)));
71 }
72
73 #[test]
74 fn displaying_native_balance_works() {
75 let balance: Balance = Default::default();
76 assert_eq!("", format!("{balance}",));
77 }
78
79 #[test]
80 fn displaying_cw20_balance_works() {
81 let balance = Balance::Cw20(Cw20CoinVerified {
82 address: Addr::unchecked("sender"),
83 amount: Uint128::zero(),
84 });
85 assert_eq!("address: sender, amount: 0", format!("{balance}",));
86 }
87
88 #[test]
89 fn default_native_balance_is_empty() {
90 assert!(Balance::default().is_empty());
91 }
92
93 #[test]
94 fn cw20_balance_with_zero_amount_is_empty() {
95 assert!(Balance::Cw20(Cw20CoinVerified {
96 address: Addr::unchecked("sender"),
97 amount: Uint128::zero(),
98 })
99 .is_empty());
100 }
101}