use serde::Deserialize;
use serde::Serialize;
use super::PeerRing;
use crate::dht::entry::EntryLookupEvidence;
use crate::dht::entry::EntryLookupKey;
use crate::dht::entry::PlacedEntry;
use crate::dht::entry::PlacedEntryOperation;
use crate::dht::entry::PlacementMiss;
use crate::dht::storage::StorageSyncPurpose;
use crate::dht::storage::StorageSyncRoute;
use crate::dht::Did;
use crate::error::Error;
use crate::error::Result;
#[derive(Clone, Debug, PartialEq)]
pub enum PeerRingAction {
None,
SomeEntry(EntryLookupEvidence),
EntryMisses(Vec<PlacementMiss>),
Some(Did),
RemoteAction(Did, RemoteAction),
MultiActions(Vec<PeerRingAction>),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RemoteAction {
FindSuccessor(Did),
FindEntry(EntryLookupKey),
FindEntryForOperate(PlacedEntryOperation),
Notify(Did),
SyncEntriesWithSuccessor {
purpose: StorageSyncPurpose,
route: StorageSyncRoute,
data: Vec<PlacedEntry>,
},
FindSuccessorForConnect(Did),
FindSuccessorForFix {
did: Did,
index: usize,
},
QueryForSuccessorList,
QueryForSuccessorListAndPred,
TryConnect,
}
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
pub struct TopoInfo {
pub successors: Vec<Did>,
pub predecessor: Option<Did>,
}
impl TopoInfo {
pub(crate) fn confirmed_by(&self, mut is_routable: impl FnMut(Did) -> bool) -> Self {
Self {
successors: self
.successors
.iter()
.copied()
.filter(|peer| is_routable(*peer))
.collect(),
predecessor: self.predecessor.filter(|peer| is_routable(*peer)),
}
}
pub(crate) fn has_confirmed_peer(&self) -> bool {
self.predecessor.is_some() || !self.successors.is_empty()
}
}
impl TryFrom<&PeerRing> for TopoInfo {
type Error = Error;
fn try_from(dht: &PeerRing) -> Result<Self> {
let state = dht.topology_state()?;
Ok(Self {
successors: state.successors,
predecessor: state.predecessor,
})
}
}
impl PeerRingAction {
pub fn is_none(&self) -> bool {
matches!(self, Self::None)
}
pub fn is_some(&self) -> bool {
matches!(self, Self::Some(_))
}
pub fn is_some_entry(&self) -> bool {
matches!(self, Self::SomeEntry(_))
}
pub fn is_remote(&self) -> bool {
matches!(self, Self::RemoteAction(..))
}
pub fn is_multi(&self) -> bool {
matches!(self, Self::MultiActions(..))
}
}
impl From<Vec<PeerRingAction>> for PeerRingAction {
fn from(actions: Vec<PeerRingAction>) -> Self {
if actions.is_empty() {
Self::None
} else {
Self::MultiActions(actions)
}
}
}