use serde::{Deserialize, Serialize};
use super::candidate::Candidate;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NatStatusSnapshot {
pub candidates: Vec<Candidate>,
pub peers: Vec<NatPeerSnapshot>,
pub last_refresh: u64,
}
impl NatStatusSnapshot {
#[must_use]
pub fn empty() -> Self {
Self {
candidates: Vec::new(),
peers: Vec::new(),
last_refresh: 0,
}
}
}
impl Default for NatStatusSnapshot {
fn default() -> Self {
Self::empty()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NatPeerSnapshot {
pub node_id: String,
pub connection_type: String,
pub remote_endpoint: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_snapshot_has_no_peers_or_candidates() {
let s = NatStatusSnapshot::empty();
assert!(s.candidates.is_empty());
assert!(s.peers.is_empty());
assert_eq!(s.last_refresh, 0);
}
#[test]
fn snapshot_default_matches_empty() {
let a = NatStatusSnapshot::default();
let b = NatStatusSnapshot::empty();
assert_eq!(a.candidates.len(), b.candidates.len());
assert_eq!(a.peers.len(), b.peers.len());
assert_eq!(a.last_refresh, b.last_refresh);
}
#[test]
fn peer_snapshot_serialises_and_round_trips() {
let peer = NatPeerSnapshot {
node_id: "node-1".to_string(),
connection_type: "direct".to_string(),
remote_endpoint: Some("203.0.113.5:51820".to_string()),
};
let json = serde_json::to_string(&peer).unwrap();
let parsed: NatPeerSnapshot = serde_json::from_str(&json).unwrap();
assert_eq!(parsed.node_id, "node-1");
assert_eq!(parsed.connection_type, "direct");
assert_eq!(parsed.remote_endpoint.as_deref(), Some("203.0.113.5:51820"));
}
}