use std::{
collections::{btree_map, BTreeMap, HashSet},
ops::Deref,
};
use solana_sdk::{address_lookup_table::AddressLookupTableAccount, pubkey::Pubkey};
#[derive(Debug, Clone, Default)]
pub struct AddressLookupTables {
pub(crate) luts: BTreeMap<Pubkey, Vec<Pubkey>>,
}
impl AddressLookupTables {
pub fn addresses(&self) -> HashSet<Pubkey> {
self.luts
.values()
.flatten()
.copied()
.collect::<HashSet<_>>()
}
pub fn is_empty(&self) -> bool {
self.luts.is_empty()
}
pub fn len(&self) -> usize {
self.luts.len()
}
pub fn add(&mut self, lut: &AddressLookupTableAccount) {
self.luts.insert(lut.key, lut.addresses.clone());
}
pub fn accounts(&self) -> impl Iterator<Item = AddressLookupTableAccount> + '_ {
self.luts
.iter()
.map(|(key, addresses)| AddressLookupTableAccount {
key: *key,
addresses: addresses.clone(),
})
}
}
impl FromIterator<(Pubkey, Vec<Pubkey>)> for AddressLookupTables {
fn from_iter<T: IntoIterator<Item = (Pubkey, Vec<Pubkey>)>>(iter: T) -> Self {
Self {
luts: FromIterator::from_iter(iter),
}
}
}
impl Extend<(Pubkey, Vec<Pubkey>)> for AddressLookupTables {
fn extend<T: IntoIterator<Item = (Pubkey, Vec<Pubkey>)>>(&mut self, iter: T) {
self.luts.extend(iter);
}
}
impl IntoIterator for AddressLookupTables {
type IntoIter = btree_map::IntoIter<Pubkey, Vec<Pubkey>>;
type Item = (Pubkey, Vec<Pubkey>);
fn into_iter(self) -> Self::IntoIter {
self.luts.into_iter()
}
}
impl Deref for AddressLookupTables {
type Target = BTreeMap<Pubkey, Vec<Pubkey>>;
fn deref(&self) -> &Self::Target {
&self.luts
}
}