use crate::DistributionFlags;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LocalNode {
pub name: NodeName,
pub flags: DistributionFlags,
pub creation: Creation,
}
impl LocalNode {
pub fn new(name: NodeName, creation: Creation) -> Self {
Self {
name,
flags: Default::default(),
creation,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct PeerNode {
pub name: NodeName,
pub flags: DistributionFlags,
pub creation: Option<Creation>,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
#[allow(missing_docs)]
pub enum NodeNameError {
#[error("node name length must be less than 256, but got {size} characters")]
TooLongName { size: usize },
#[error("the name part of a node name is empty")]
EmptyName,
#[error("the host part of a node name is empty")]
EmptyHost,
#[error("node name must contain an '@' character")]
MissingAtmark,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct NodeName {
name: String,
host: String,
}
impl NodeName {
pub fn new(name: &str, host: &str) -> Result<Self, NodeNameError> {
let size = name.len() + 1 + host.len();
if size > 255 {
Err(NodeNameError::TooLongName { size })
} else if name.is_empty() {
Err(NodeNameError::EmptyName)
} else if host.is_empty() {
Err(NodeNameError::EmptyHost)
} else {
Ok(Self {
name: name.to_owned(),
host: host.to_owned(),
})
}
}
pub fn name(&self) -> &str {
&self.name
}
pub fn host(&self) -> &str {
&self.host
}
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
self.name.len() + 1 + self.host.len()
}
}
impl std::str::FromStr for NodeName {
type Err = NodeNameError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut tokens = s.splitn(2, '@');
if let (Some(name), Some(host)) = (tokens.next(), tokens.next()) {
Self::new(name, host)
} else {
Err(NodeNameError::MissingAtmark)
}
}
}
impl std::fmt::Display for NodeName {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}@{}", self.name, self.host)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Creation(u32);
impl Creation {
pub const fn new(n: u32) -> Self {
Self(n)
}
pub fn random() -> Self {
Self(rand::random())
}
pub const fn get(self) -> u32 {
self.0
}
}