1use std::ops::{Add, AddAssign, Sub, SubAssign};
9
10#[derive(Clone, Copy, Debug, Default)]
26pub struct CostChange {
27 deduct: u64,
28 reward: u64,
29}
30
31impl CostChange {
32 pub const fn deduct(value: u64) -> Self {
33 Self {
34 deduct: value,
35 reward: 0,
36 }
37 }
38 pub const fn reward(value: u64) -> Self {
39 Self {
40 deduct: 0,
41 reward: value,
42 }
43 }
44 pub fn values(&self) -> (u64, u64) {
45 (
46 self.deduct.saturating_sub(self.reward),
47 self.reward.saturating_sub(self.deduct),
48 )
49 }
50}
51
52impl AddAssign for CostChange {
53 fn add_assign(&mut self, rhs: Self) {
54 self.deduct = self.deduct.saturating_add(rhs.deduct);
55 self.reward = self.reward.saturating_add(rhs.reward);
56 }
57}
58
59impl Add for CostChange {
60 type Output = Self;
61 fn add(self, other: Self) -> Self {
62 Self {
63 deduct: self.deduct.saturating_add(other.deduct),
64 reward: self.reward.saturating_add(other.reward),
65 }
66 }
67}
68
69impl SubAssign for CostChange {
70 fn sub_assign(&mut self, rhs: Self) {
71 let v = self.sub(rhs);
72 *self = v;
73 }
74}
75
76impl Sub for CostChange {
77 type Output = Self;
78 fn sub(self, other: Self) -> Self {
79 let net_deduct = other.deduct.saturating_sub(self.deduct);
80 let net_reward = other.reward.saturating_sub(self.reward);
81 Self {
82 deduct: self.deduct.saturating_sub(other.deduct) + net_reward,
83 reward: self.reward.saturating_sub(other.reward) + net_deduct,
84 }
85 }
86}
87#[test]
88fn test_cost_change() {
89 let mut change = CostChange::default(); change += CostChange::reward(1); change += CostChange::deduct(2); assert_eq!(change.values(), (1, 0));
93 change -= CostChange::deduct(3); change -= CostChange::reward(0); assert_eq!(change.values(), (0, 2));
96}