pub mod announce;
pub use announce::{Announcer, AnnouncerConfig, AnnouncerError, AnnouncerResult};
pub mod fetch;
pub use fetch::{Fetcher, FetcherConfig, FetcherError, FetcherResult};
use std::collections::BTreeSet;
use crate::identity::Visibility;
use crate::prelude::Doc;
use super::NodeId;
pub const DEFAULT_REPLICATION_FACTOR: usize = 3;
pub struct PrivateNetwork {
allowed: BTreeSet<NodeId>,
}
impl PrivateNetwork {
pub fn private_repo(doc: &Doc) -> Option<Self> {
match doc.visibility() {
Visibility::Public => None,
Visibility::Private { allow } => {
let allowed = doc
.delegates()
.iter()
.chain(allow.iter())
.map(|did| *did.as_key())
.collect();
Some(Self { allowed })
}
}
}
pub fn restrict<P>(self, predicate: P) -> Self
where
P: FnMut(&NodeId) -> bool,
{
Self {
allowed: self.allowed.into_iter().filter(predicate).collect(),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ReplicationFactor {
MustReach(usize),
Range(ReplicationRange),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct ReplicationRange {
lower: usize,
upper: usize,
}
impl Default for ReplicationFactor {
fn default() -> Self {
Self::must_reach(DEFAULT_REPLICATION_FACTOR)
}
}
impl ReplicationFactor {
pub fn range(lower: usize, upper: usize) -> Self {
if lower >= upper {
Self::MustReach(lower)
} else {
Self::Range(ReplicationRange { lower, upper })
}
}
pub fn must_reach(factor: usize) -> Self {
Self::MustReach(factor)
}
pub fn lower_bound(&self) -> usize {
match self {
Self::MustReach(lower) => *lower,
Self::Range(ReplicationRange { lower: min, .. }) => *min,
}
}
pub fn upper_bound(&self) -> Option<usize> {
match self {
Self::MustReach(_) => None,
Self::Range(ReplicationRange { upper: max, .. }) => Some(*max),
}
}
pub fn min(self, new: usize) -> Self {
match self {
Self::MustReach(min) => Self::MustReach(min.min(new)),
Self::Range(ReplicationRange {
lower: min,
upper: max,
}) => Self::range(min, max.min(new)),
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn ensure_replicas_construction() {
let replicas = ReplicationFactor::range(1, 3);
assert!(
replicas.lower_bound()
<= replicas
.upper_bound()
.expect("replicas should have max value")
);
let replicas = ReplicationFactor::range(1, 1);
assert!(replicas.upper_bound().is_none());
let replicas = ReplicationFactor::range(3, 1);
assert!(replicas.upper_bound().is_none());
}
#[test]
fn replicas_constrain_to() {
let replicas = ReplicationFactor::must_reach(3).min(1);
assert_eq!(replicas, ReplicationFactor::MustReach(1));
let replicas = ReplicationFactor::must_reach(3).min(3);
assert_eq!(replicas, ReplicationFactor::MustReach(3));
let replicas = ReplicationFactor::must_reach(3).min(10);
assert_eq!(replicas, ReplicationFactor::MustReach(3));
let replicas = ReplicationFactor::range(1, 3).min(1);
assert_eq!(replicas, ReplicationFactor::MustReach(1));
let replicas = ReplicationFactor::range(1, 3).min(3);
assert_eq!(
replicas,
ReplicationFactor::Range(ReplicationRange { lower: 1, upper: 3 })
);
let replicas = ReplicationFactor::range(1, 3).min(10);
assert_eq!(
replicas,
ReplicationFactor::Range(ReplicationRange { lower: 1, upper: 3 })
);
}
}