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,
}
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(),
}
}
pub fn with_priority(
transport: impl Into<String>,
addr: impl Into<String>,
priority: u8,
) -> Self {
Self {
transport: transport.into(),
addr: addr.into(),
priority,
}
}
}
#[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)
}
}