1use std::{
2 collections::BTreeMap,
3 mem,
4 ops::{Add, AddAssign},
5};
6
7use brk_core::{OutputType, Sats};
8
9use super::{OutputsByType, SupplyState};
10
11#[derive(Default, Debug)]
12pub struct Transacted {
13 pub spendable_supply: SupplyState,
14 pub by_type: OutputsByType<SupplyState>,
15 pub by_size_group: BTreeMap<usize, SupplyState>,
16}
17
18impl Transacted {
19 #[allow(clippy::inconsistent_digit_grouping)]
20 pub fn iterate(&mut self, value: Sats, _type: OutputType) {
21 let supply = SupplyState { utxos: 1, value };
22
23 *self.by_type.get_mut(_type) += &supply;
24
25 if _type.is_unspendable() {
26 return;
27 }
28
29 self.spendable_supply += &supply;
30
31 let _value = usize::from(value);
32
33 if _value == 0 {
35 *self.by_size_group.entry(0).or_default() += &supply;
36 } else if _value < 10 {
37 *self.by_size_group.entry(1).or_default() += &supply;
38 } else if _value < 100 {
39 *self.by_size_group.entry(10).or_default() += &supply;
40 } else if _value < 1_000 {
41 *self.by_size_group.entry(100).or_default() += &supply;
42 } else if _value < 10_000 {
43 *self.by_size_group.entry(1_000).or_default() += &supply;
44 } else if _value < 100_000 {
45 *self.by_size_group.entry(10_000).or_default() += &supply;
46 } else if _value < 1_000_000 {
47 *self.by_size_group.entry(100_000).or_default() += &supply;
48 } else if _value < 10_000_000 {
49 *self.by_size_group.entry(1_000_000).or_default() += &supply;
50 } else if _value < 1_00_000_000 {
51 *self.by_size_group.entry(10_000_000).or_default() += &supply;
52 } else if _value < 10_00_000_000 {
53 *self.by_size_group.entry(1_00_000_000).or_default() += &supply;
54 } else if _value < 100_00_000_000 {
55 *self.by_size_group.entry(10_00_000_000).or_default() += &supply;
56 } else if _value < 1_000_00_000_000 {
57 *self.by_size_group.entry(100_00_000_000).or_default() += &supply;
58 } else if _value < 10_000_00_000_000 {
59 *self.by_size_group.entry(1_000_00_000_000).or_default() += &supply;
60 } else if _value < 100_000_00_000_000 {
61 *self.by_size_group.entry(10_000_00_000_000).or_default() += &supply;
62 } else {
63 *self.by_size_group.entry(100_000_00_000_000).or_default() += &supply;
64 }
65 }
66
67 fn merge_by_size(
68 first: BTreeMap<usize, SupplyState>,
69 second: BTreeMap<usize, SupplyState>,
70 ) -> BTreeMap<usize, SupplyState> {
71 let (mut source, to_consume) = if first.len() > second.len() {
72 (first, second)
73 } else {
74 (second, first)
75 };
76 to_consume.into_iter().for_each(|(k, v)| {
77 *source.entry(k).or_default() += &v;
78 });
79 source
80 }
81}
82
83impl Add for Transacted {
84 type Output = Self;
85 fn add(self, rhs: Self) -> Self::Output {
86 Self {
87 spendable_supply: self.spendable_supply + rhs.spendable_supply,
88 by_type: self.by_type + rhs.by_type,
89 by_size_group: Self::merge_by_size(self.by_size_group, rhs.by_size_group),
90 }
91 }
92}
93
94impl AddAssign for Transacted {
95 fn add_assign(&mut self, rhs: Self) {
96 self.by_size_group =
97 Self::merge_by_size(mem::take(&mut self.by_size_group), rhs.by_size_group);
98 self.spendable_supply += &rhs.spendable_supply;
99 self.by_type += rhs.by_type;
100 }
101}