1use std::borrow::Borrow;
2
3use num_traits::{CheckedSub, Zero};
4
5pub trait Bank<K> {
7 type Num;
9
10 fn record_transferred_in_by_token<Q: Borrow<K> + ?Sized>(
12 &mut self,
13 token: &Q,
14 amount: &Self::Num,
15 ) -> crate::Result<()>;
16
17 fn record_transferred_out_by_token<Q: Borrow<K> + ?Sized>(
19 &mut self,
20 token: &Q,
21 amount: &Self::Num,
22 ) -> crate::Result<()>;
23
24 fn balance<Q: Borrow<K> + ?Sized>(&self, token: &Q) -> crate::Result<Self::Num>;
26
27 fn balance_excluding<Q: Borrow<K> + ?Sized>(
29 &self,
30 token: &Q,
31 excluded: &Self::Num,
32 ) -> crate::Result<Self::Num>
33 where
34 Self::Num: CheckedSub + Zero,
35 {
36 let balance = self.balance(token)?;
37 if excluded.is_zero() {
38 Ok(balance)
39 } else {
40 balance
41 .checked_sub(excluded)
42 .ok_or(crate::Error::Computation(
43 "underflow when excluding amount of balance",
44 ))
45 }
46 }
47}