use serde::{Deserialize, Serialize};
use crate::NetworkAddress;
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct NodeAddress {
address: NetworkAddress,
generation: u64,
}
impl NodeAddress {
pub fn new(address: NetworkAddress, generation: u64) -> Self {
Self {
address,
generation,
}
}
pub fn address(&self) -> &NetworkAddress {
&self.address
}
pub fn generation(&self) -> u64 {
self.generation
}
}
impl std::fmt::Display for NodeAddress {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}@gen{}", self.address, self.generation)
}
}
#[cfg(test)]
mod tests {
use std::net::{IpAddr, Ipv4Addr};
use super::*;
#[test]
fn test_node_address_equality() {
let addr = NetworkAddress::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 4500);
let n1 = NodeAddress::new(addr.clone(), 1);
let n2 = NodeAddress::new(addr.clone(), 1);
let n3 = NodeAddress::new(addr, 2);
assert_eq!(n1, n2);
assert_ne!(n1, n3);
}
#[test]
fn test_node_address_accessors() {
let addr = NetworkAddress::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 4500);
let node = NodeAddress::new(addr.clone(), 42);
assert_eq!(node.address(), &addr);
assert_eq!(node.generation(), 42);
}
#[test]
fn test_node_address_display() {
let addr = NetworkAddress::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 4500);
let node = NodeAddress::new(addr, 7);
assert_eq!(node.to_string(), "127.0.0.1:4500@gen7");
}
#[test]
fn test_node_address_serde_roundtrip() {
let addr = NetworkAddress::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 4500);
let node = NodeAddress::new(addr, 42);
let json = serde_json::to_string(&node).expect("serialize");
let decoded: NodeAddress = serde_json::from_str(&json).expect("deserialize");
assert_eq!(node, decoded);
}
#[test]
fn test_node_address_hash_works_in_collections() {
use std::collections::HashSet;
let addr = NetworkAddress::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 4500);
let mut set = HashSet::new();
set.insert(NodeAddress::new(addr.clone(), 1));
set.insert(NodeAddress::new(addr.clone(), 2));
set.insert(NodeAddress::new(addr, 1));
assert_eq!(set.len(), 2);
}
}