1use std::net::{IpAddr, SocketAddr};
5
6use crate::NodeId;
7
8pub trait ShortFormat {
11 fn fmt_short(&self) -> String;
12}
13
14impl ShortFormat for NodeId {
15 fn fmt_short(&self) -> String {
16 self.to_hex()[0..10].to_string()
17 }
18}
19
20impl ShortFormat for iroh::EndpointId {
21 fn fmt_short(&self) -> String {
22 self.to_string()[0..10].to_string()
23 }
24}
25
26impl ShortFormat for [u8; 32] {
27 fn fmt_short(&self) -> String {
28 hex::encode(&self[0..5]).to_string()
29 }
30}
31
32impl ShortFormat for Vec<u8> {
33 fn fmt_short(&self) -> String {
34 hex::encode(&self[0..5]).to_string()
35 }
36}
37
38impl ShortFormat for Vec<NodeId> {
39 fn fmt_short(&self) -> String {
40 let list: Vec<String> = self.iter().map(|addr| addr.fmt_short()).collect();
41 format!("[{}]", list.join(", "))
42 }
43}
44
45impl ShortFormat for Vec<iroh::EndpointId> {
46 fn fmt_short(&self) -> String {
47 let list: Vec<String> = self
48 .iter()
49 .map(|addr| addr.fmt_short().to_string())
50 .collect();
51 format!("[{}]", list.join(", "))
52 }
53}
54
55#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
61pub enum ConnectivityStatus {
62 Other,
64
65 Local,
67
68 Global,
70}
71
72impl ConnectivityStatus {
73 pub fn is_global(&self) -> bool {
74 self == &ConnectivityStatus::Global
75 }
76}
77
78pub fn connectivity_status(addr: &SocketAddr) -> ConnectivityStatus {
81 match addr.ip() {
82 IpAddr::V4(ip) => {
83 if ip.is_loopback() || ip.is_link_local() || ip.is_private() {
84 ConnectivityStatus::Local
85 } else if ip.is_multicast()
86 || ip.is_broadcast()
87 || ip.is_documentation()
88 || ip.is_unspecified()
89 {
90 ConnectivityStatus::Other
91 } else {
92 ConnectivityStatus::Global
93 }
94 }
95 IpAddr::V6(ip) => {
96 if ip.is_loopback() || ip.is_unique_local() || ip.is_unicast_link_local() {
97 ConnectivityStatus::Local
98 } else if ip.is_multicast() || ip.is_unspecified() {
99 ConnectivityStatus::Other
100 } else {
101 ConnectivityStatus::Global
102 }
103 }
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::ConnectivityStatus;
110
111 #[test]
112 fn order() {
113 assert!(ConnectivityStatus::Global > ConnectivityStatus::Local);
114 assert!(ConnectivityStatus::Local > ConnectivityStatus::Other);
115 }
116}