use {
crate::{
PeerId,
primitives::{IntoIterOrSingle, Tag},
},
core::time::Duration,
derive_builder::Builder,
iroh::EndpointAddr,
serde::{Deserialize, Serialize},
};
#[derive(Debug, Clone, Builder, Serialize, Deserialize, PartialEq)]
#[builder(pattern = "owned", setter(prefix = "with"), derive(Debug, Clone))]
#[builder_struct_attr(doc(hidden))]
pub struct Config {
#[builder(default = "100")]
pub events_backlog: usize,
#[builder(default = "Vec::new()", setter(custom))]
pub bootstrap_peers: Vec<EndpointAddr>,
#[builder(default = "Vec::new()", setter(custom))]
pub tags: Vec<Tag>,
#[builder(default = "Duration::from_secs(300)")]
pub purge_after: Duration,
#[builder(default = "Duration::from_secs(50)")]
pub max_time_drift: Duration,
#[builder(default = "Duration::from_secs(45)")]
pub announce_interval: Duration,
#[builder(default = "0.5")]
pub announce_jitter: f32,
#[builder(default = "false")]
pub no_auto_bootstrap: bool,
#[builder(setter(skip), default = "Duration::from_millis(500)")]
pub graceful_departure_window: Duration,
}
impl Config {
pub fn builder() -> ConfigBuilder {
ConfigBuilder::default()
}
pub fn bootstrap_peers_ids(&self) -> Vec<PeerId> {
self.bootstrap_peers.iter().map(|addr| addr.id).collect()
}
}
impl ConfigBuilder {
#[must_use]
pub fn with_bootstrap<V>(
mut self,
peers: impl IntoIterOrSingle<EndpointAddr, V>,
) -> Self {
if let Some(existing) = &mut self.bootstrap_peers {
existing.extend(peers.iterator());
} else {
self.bootstrap_peers = Some(peers.iterator().into_iter().collect());
}
self
}
#[must_use]
pub fn with_tags<V>(mut self, tags: impl IntoIterOrSingle<Tag, V>) -> Self {
let tags: Vec<Tag> = tags.iterator().into_iter().collect();
if let Some(existing) = &mut self.tags {
existing.extend(tags);
} else {
self.tags = Some(tags);
}
self
}
#[must_use]
pub const fn no_auto_bootstrap(mut self) -> Self {
self.no_auto_bootstrap = Some(true);
self
}
}
#[doc(hidden)]
pub trait IntoConfig {
fn into_config(self) -> Result<Config, ConfigBuilderError>;
}
impl IntoConfig for Config {
fn into_config(self) -> Result<Config, ConfigBuilderError> {
Ok(self)
}
}
impl IntoConfig for ConfigBuilder {
fn into_config(self) -> Result<Config, ConfigBuilderError> {
self.build()
}
}