use serde::Deserialize;
use serde::Serialize;
use super::compress_iter;
use crate::dht::entry::Entry;
use crate::dht::EntryStorage;
use crate::dht::PeerRing;
use crate::swarm::Swarm;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SwarmInspect {
pub peers: Vec<ConnectionInspect>,
pub dht: DHTInspect,
pub persistence_storage: StorageInspect,
pub cache_storage: StorageInspect,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConnectionInspect {
pub did: String,
pub state: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DHTInspect {
pub did: String,
pub successors: Vec<String>,
#[serde(default)]
pub predecessor: Option<String>,
pub finger_table: Vec<(Option<String>, u64, u64)>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct StorageInspect {
pub items: Vec<(String, Entry)>,
}
impl SwarmInspect {
pub async fn inspect(swarm: &Swarm) -> Self {
let dht = DHTInspect::inspect(&swarm.dht());
let peers = swarm.peers();
let persistence_storage = StorageInspect::inspect_kv_storage(&swarm.dht().storage).await;
let cache_storage = StorageInspect::inspect_kv_storage(&swarm.dht().cache).await;
Self {
peers,
dht,
persistence_storage,
cache_storage,
}
}
}
impl DHTInspect {
pub fn inspect(dht: &PeerRing) -> Self {
let did = dht.did.to_string();
let topology = dht.topology_state().ok();
let successors = topology
.as_ref()
.map(|state| {
state
.successors
.iter()
.copied()
.map(|s| s.to_string())
.collect()
})
.unwrap_or_default();
let predecessor = topology
.as_ref()
.and_then(|state| state.predecessor)
.map(|predecessor| predecessor.to_string());
let finger_table = topology
.map(|state| {
compress_iter(
state
.fingers
.into_iter()
.map(|finger| finger.map(|did| did.to_string())),
)
})
.unwrap_or_default();
Self {
did,
successors,
predecessor,
finger_table,
}
}
}
impl StorageInspect {
pub async fn inspect_kv_storage(storage: &EntryStorage) -> Self {
Self {
items: storage
.get_all()
.await
.unwrap_or_default()
.into_iter()
.collect(),
}
}
}