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
/// Byte to integer conversion
pub mod byte_utils;
/// Clock provider
pub mod clock;
/// Cryptographic utilities
pub mod crypto_utils;
/// Logging macros
#[macro_use]
#[allow(unused_macros)]
pub mod macro_logger;
#[macro_use]
/// Debugging
pub mod debug_utils;
/// Logging
pub mod log_utils;
/// An implementation of the LDK Sign trait for integration with LDK based nodes
pub mod loopback;
#[allow(missing_docs)]
pub mod test_logger;
#[allow(missing_docs)]
#[cfg(any(test, feature = "test_utils"))]
#[macro_use]
pub mod test_utils;
#[allow(missing_docs)]
/// Key utilities
pub mod key_utils;
#[cfg(test)]
pub(crate) mod mocks;
/// serde for foreign types
#[allow(missing_docs)]
pub mod ser_util;
/// Status error results
pub mod status;
/// Transaction utilities
pub mod transaction_utils;
/// Velocity control
pub mod velocity;

/// The initial commitment number when counting backwards
pub const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;

use crate::prelude::*;
use core::slice::Iter;
use itertools::{put_back, PutBack};

/// Iterator over elements in `to` that are not in `from`
pub struct AddedItemsIter<'a, T: Ord + Eq> {
    from: PutBack<Iter<'a, T>>,
    to: PutBack<Iter<'a, T>>,
}

impl<'a, T: Ord + Eq> AddedItemsIter<'a, T> {
    /// Both vectors must be sorted
    pub fn new(from: &'a Vec<T>, to: &'a Vec<T>) -> Self {
        AddedItemsIter { from: put_back(from.iter()), to: put_back(to.iter()) }
    }
}

impl<'a, T: Ord + Eq> Iterator for AddedItemsIter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            match self.from.next() {
                // Nothing in `from` - yield remaining elements in `to`
                None => return self.to.next(),
                Some(next_from) => {
                    match self.to.next() {
                        // Nothing in `to` - done
                        None => return None,
                        Some(next_to) => {
                            if next_from < next_to {
                                // `from` is behind - consume `from` but not `to`
                                self.to.put_back(next_to);
                                continue;
                            } else if next_from == next_to {
                                // consume both
                                continue;
                            } else {
                                // `to` is behind - consume `to` but not `from`
                                self.from.put_back(next_from);
                                return Some(next_to);
                            }
                        }
                    }
                }
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::util::AddedItemsIter;

    #[test]
    fn delta_test() {
        fn check(from: Vec<u8>, to: Vec<u8>, expect: Vec<u8>) {
            assert_eq!(AddedItemsIter::new(&from, &to).cloned().collect::<Vec<u8>>(), expect);
        }

        check(vec![], vec![1, 2, 4], vec![1, 2, 4]);
        check(vec![3], vec![1, 2, 4], vec![1, 2, 4]);
        check(vec![2, 3], vec![1, 2, 4], vec![1, 4]);
        check(vec![1, 2, 3], vec![1, 2, 4], vec![4]);
        check(vec![0, 1, 2, 3], vec![1, 2, 4], vec![4]);
        check(vec![0, 1, 3], vec![1, 2, 4], vec![2, 4]);
        check(vec![0, 1, 3], vec![1, 2, 4, 5], vec![2, 4, 5]);
    }
}