samotop_core/io/
connection.rs1use crate::common::Identify;
2use std::time::{Duration, SystemTime};
3
4#[derive(Clone, Debug, PartialEq, Eq)]
6pub struct ConnectionInfo {
7 pub id: String,
8 pub local_addr: String,
9 pub peer_addr: String,
10 pub established: SystemTime,
11}
12
13impl ConnectionInfo {
14 pub fn new(local_addr: String, peer_addr: String) -> Self {
15 ConnectionInfo {
16 id: Identify::now().to_string(),
17 local_addr,
18 peer_addr,
19 established: SystemTime::now(),
20 }
21 }
22 pub fn age(&self) -> Duration {
23 self.established.elapsed().unwrap_or(Duration::ZERO)
24 }
25}
26impl Default for ConnectionInfo {
27 fn default() -> Self {
28 ConnectionInfo::new(String::default(), String::default())
29 }
30}
31
32impl std::fmt::Display for ConnectionInfo {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
34 write!(f, "connection id {} from peer ", self.id)?;
35 if self.peer_addr.is_empty() {
36 f.write_str("Unknown")?;
37 } else {
38 f.write_str(self.peer_addr.as_str())?;
39 }
40 write!(f, " to local ")?;
41 if self.local_addr.is_empty() {
42 f.write_str("Unknown")?;
43 } else {
44 f.write_str(self.local_addr.as_str())?;
45 }
46 write!(f, " established {}s ago", self.age().as_secs_f64())?;
47 Ok(())
48 }
49}
50
51#[cfg(test)]
52mod store_tests {
53 use regex::Regex;
54
55 use super::*;
56
57 #[test]
58 pub fn display_connection_info() {
59 let sut = ConnectionInfo {
60 established: SystemTime::UNIX_EPOCH,
61 ..Default::default()
62 };
63 let dump = sut.to_string();
64 let dump = Regex::new("[0-9]+")
65 .expect("regex")
66 .replace_all(&dump, "--redaced--");
67 insta::assert_display_snapshot!(dump, @"connection id --redaced-- from peer Unknown to local Unknown established --redaced--.--redaced--s ago");
68 }
69
70 #[test]
71 pub fn timely_connection_info() {
72 let sut = ConnectionInfo::default();
73 assert!(sut.established.elapsed().expect("duration").as_secs() < 1)
74 }
75
76 #[test]
77 pub fn unique_connection_info() {
78 let sut1 = ConnectionInfo::default();
79 let sut2 = ConnectionInfo::default();
80 assert_ne!(sut1.id, sut2.id);
81 }
82}