abstract_cw20/
balance.rs

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    /// normalize Wallet
42    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}