use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ConnectPolicy {
#[default]
AutoConnect,
OnDemand,
Manual,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PeerAddress {
pub transport: String,
pub addr: String,
#[serde(default = "default_priority")]
pub priority: u8,
#[serde(default, skip_serializing_if = "Option::is_none", skip_deserializing)]
pub seen_at_ms: Option<u64>,
}
impl PartialEq for PeerAddress {
fn eq(&self, other: &Self) -> bool {
self.transport == other.transport
&& self.addr == other.addr
&& self.priority == other.priority
}
}
impl Eq for PeerAddress {}
fn default_priority() -> u8 {
100
}
fn default_auto_reconnect() -> bool {
true
}
impl PeerAddress {
pub fn new(transport: impl Into<String>, addr: impl Into<String>) -> Self {
Self {
transport: transport.into(),
addr: addr.into(),
priority: default_priority(),
seen_at_ms: None,
}
}
pub fn with_priority(
transport: impl Into<String>,
addr: impl Into<String>,
priority: u8,
) -> Self {
Self {
transport: transport.into(),
addr: addr.into(),
priority,
seen_at_ms: None,
}
}
pub fn with_seen_at_ms(mut self, seen_at_ms: u64) -> Self {
self.seen_at_ms = Some(seen_at_ms);
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PeerConfig {
pub npub: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub alias: Option<String>,
#[serde(default)]
pub addresses: Vec<PeerAddress>,
#[serde(default)]
pub connect_policy: ConnectPolicy,
#[serde(default = "default_auto_reconnect")]
pub auto_reconnect: bool,
}
impl Default for PeerConfig {
fn default() -> Self {
Self {
npub: String::new(),
alias: None,
addresses: Vec::new(),
connect_policy: ConnectPolicy::default(),
auto_reconnect: default_auto_reconnect(),
}
}
}
impl PeerConfig {
pub fn new(
npub: impl Into<String>,
transport: impl Into<String>,
addr: impl Into<String>,
) -> Self {
Self {
npub: npub.into(),
alias: None,
addresses: vec![PeerAddress::new(transport, addr)],
connect_policy: ConnectPolicy::default(),
auto_reconnect: default_auto_reconnect(),
}
}
pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
self.alias = Some(alias.into());
self
}
pub fn with_address(mut self, addr: PeerAddress) -> Self {
self.addresses.push(addr);
self
}
pub fn addresses_by_priority(&self) -> Vec<&PeerAddress> {
let mut addrs: Vec<_> = self.addresses.iter().collect();
addrs.sort_by_key(|a| a.priority);
addrs
}
pub fn is_auto_connect(&self) -> bool {
matches!(self.connect_policy, ConnectPolicy::AutoConnect)
}
}