1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use std::{
    collections::btree_map,
    fmt::{self, Debug, Formatter},
    iter::FusedIterator,
    num::NonZeroU128,
};

use crate::{asset::Id, Value};

use super::{Balance, Imbalance};

impl Balance {
    pub(super) fn iter(&self) -> Iter<'_> {
        Iter {
            negated: self.negated,
            iter: self.balance.iter(),
        }
    }
}

impl IntoIterator for Balance {
    type Item = Imbalance<Value>;
    type IntoIter = IntoIter;

    fn into_iter(self) -> Self::IntoIter {
        IntoIter {
            negated: self.negated,
            iter: self.balance.into_iter(),
        }
    }
}

#[derive(Clone)]
pub struct Iter<'a> {
    negated: bool,
    iter: btree_map::Iter<'a, Id, Imbalance<NonZeroU128>>,
}

impl Debug for Iter<'_> {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        f.debug_list().entries(self.clone()).finish()
    }
}

impl Iterator for Iter<'_> {
    type Item = Imbalance<Value>;

    fn next(&mut self) -> Option<Self::Item> {
        let (&asset_id, &imbalance) = self.iter.next()?;
        let mut value_imbalance = imbalance.map(move |amount| Value {
            asset_id,
            amount: amount.into(),
        });
        if self.negated {
            value_imbalance = -value_imbalance;
        }
        Some(value_imbalance)
    }
}

impl DoubleEndedIterator for Iter<'_> {
    fn next_back(&mut self) -> Option<Self::Item> {
        let (&asset_id, &imbalance) = self.iter.next_back()?;
        let mut value_imbalance = imbalance.map(move |amount| Value {
            asset_id,
            amount: amount.into(),
        });
        if self.negated {
            value_imbalance = -value_imbalance;
        }
        Some(value_imbalance)
    }
}

impl ExactSizeIterator for Iter<'_> {
    fn len(&self) -> usize {
        self.iter.len()
    }
}

impl FusedIterator for Iter<'_> {}

pub struct IntoIter {
    negated: bool,
    iter: btree_map::IntoIter<Id, Imbalance<NonZeroU128>>,
}

impl Iterator for IntoIter {
    type Item = Imbalance<Value>;

    fn next(&mut self) -> Option<Self::Item> {
        let (asset_id, imbalance) = self.iter.next()?;
        let mut value_imbalance = imbalance.map(move |amount| Value {
            asset_id,
            amount: amount.into(),
        });
        if self.negated {
            value_imbalance = -value_imbalance;
        }
        Some(value_imbalance)
    }
}

impl DoubleEndedIterator for IntoIter {
    fn next_back(&mut self) -> Option<Self::Item> {
        let (asset_id, imbalance) = self.iter.next_back()?;
        let mut value_imbalance = imbalance.map(move |amount| Value {
            asset_id,
            amount: amount.into(),
        });
        if self.negated {
            value_imbalance = -value_imbalance;
        }
        Some(value_imbalance)
    }
}

impl ExactSizeIterator for IntoIter {
    fn len(&self) -> usize {
        self.iter.len()
    }
}

impl FusedIterator for IntoIter {}