templar_vault_kernel/
address_book.rs

1use alloc::vec::Vec;
2
3use crate::types::Address;
4
5/// Simple address map for resolving kernel addresses to chain-specific values.
6#[cfg_attr(not(target_arch = "wasm32"), derive(Debug))]
7#[derive(Clone, PartialEq, Eq)]
8pub struct AddressBook<T> {
9    addresses: Vec<(Address, T)>,
10}
11
12impl<T> Default for AddressBook<T> {
13    fn default() -> Self {
14        Self {
15            addresses: Vec::new(),
16        }
17    }
18}
19
20impl<T> AddressBook<T> {
21    /// Create an empty address book.
22    #[inline]
23    #[must_use]
24    pub fn new() -> Self {
25        Self {
26            addresses: Vec::new(),
27        }
28    }
29
30    /// Insert or update an address mapping.
31    #[inline]
32    pub fn insert(&mut self, address: Address, value: T) {
33        if let Some((_, existing)) = self
34            .addresses
35            .iter_mut()
36            .find(|(candidate, _)| *candidate == address)
37        {
38            *existing = value;
39            return;
40        }
41        self.addresses.push((address, value));
42    }
43
44    /// Resolve a kernel address to a stored value.
45    #[inline]
46    #[must_use]
47    pub fn resolve(&self, address: &Address) -> Option<&T> {
48        self.addresses
49            .iter()
50            .find(|(candidate, _)| candidate == address)
51            .map(|(_, value)| value)
52    }
53
54    /// Returns true if the address exists in the map.
55    #[inline]
56    #[must_use]
57    pub fn contains(&self, address: &Address) -> bool {
58        self.addresses
59            .iter()
60            .any(|(candidate, _)| candidate == address)
61    }
62
63    /// Returns the number of entries in the address book.
64    #[inline]
65    #[must_use]
66    pub fn len(&self) -> usize {
67        self.addresses.len()
68    }
69
70    /// Returns true if the address book is empty.
71    #[inline]
72    #[must_use]
73    pub fn is_empty(&self) -> bool {
74        self.addresses.is_empty()
75    }
76
77    #[inline]
78    pub fn clear(&mut self) {
79        self.addresses.clear();
80    }
81}
82
83impl<T> From<Vec<(Address, T)>> for AddressBook<T> {
84    fn from(addresses: Vec<(Address, T)>) -> Self {
85        let mut book = Self::new();
86        for (address, value) in addresses {
87            book.insert(address, value);
88        }
89        book
90    }
91}
92
93#[cfg(test)]
94mod tests {
95    use super::AddressBook;
96    use alloc::vec;
97
98    fn address(byte: u8) -> crate::Address {
99        crate::Address([byte; 32])
100    }
101
102    #[test]
103    fn from_vec_overwrites_duplicate_addresses() {
104        let book = AddressBook::from(vec![(address(1), 10u32), (address(1), 20u32)]);
105
106        assert_eq!(book.len(), 1);
107        assert_eq!(book.resolve(&address(1)), Some(&20u32));
108    }
109}