1use std::net::{IpAddr, SocketAddr};
5
6use p2panda_core::Topic;
7
8use crate::NodeId;
9
10pub trait ShortFormat {
13 fn fmt_short(&self) -> String;
14}
15
16impl ShortFormat for NodeId {
17 fn fmt_short(&self) -> String {
18 self.to_hex()[0..10].to_string()
19 }
20}
21
22impl ShortFormat for iroh_base::EndpointId {
23 fn fmt_short(&self) -> String {
24 self.to_string()[0..10].to_string()
25 }
26}
27
28impl ShortFormat for [u8; 32] {
29 fn fmt_short(&self) -> String {
30 hex::encode(&self[0..5]).to_string()
31 }
32}
33
34impl ShortFormat for Topic {
35 fn fmt_short(&self) -> String {
36 self.to_string()[0..10].to_string()
37 }
38}
39
40impl ShortFormat for Vec<u8> {
41 fn fmt_short(&self) -> String {
42 hex::encode(&self[0..5]).to_string()
43 }
44}
45
46impl ShortFormat for Vec<NodeId> {
47 fn fmt_short(&self) -> String {
48 let list: Vec<String> = self.iter().map(|addr| addr.fmt_short()).collect();
49 format!("[{}]", list.join(", "))
50 }
51}
52
53impl ShortFormat for Vec<iroh_base::EndpointId> {
54 fn fmt_short(&self) -> String {
55 let list: Vec<String> = self
56 .iter()
57 .map(|addr| addr.fmt_short().to_string())
58 .collect();
59 format!("[{}]", list.join(", "))
60 }
61}
62
63#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
69pub enum ConnectivityStatus {
70 Other,
72
73 Local,
75
76 Global,
78}
79
80impl ConnectivityStatus {
81 pub fn is_global(&self) -> bool {
82 self == &ConnectivityStatus::Global
83 }
84}
85
86pub fn connectivity_status(addr: &SocketAddr) -> ConnectivityStatus {
89 match addr.ip() {
90 IpAddr::V4(ip) => {
91 if ip.is_loopback() || ip.is_link_local() || ip.is_private() {
92 ConnectivityStatus::Local
93 } else if ip.is_multicast()
94 || ip.is_broadcast()
95 || ip.is_documentation()
96 || ip.is_unspecified()
97 {
98 ConnectivityStatus::Other
99 } else {
100 ConnectivityStatus::Global
101 }
102 }
103 IpAddr::V6(ip) => {
104 if ip.is_loopback() || ip.is_unique_local() || ip.is_unicast_link_local() {
105 ConnectivityStatus::Local
106 } else if ip.is_multicast() || ip.is_unspecified() {
107 ConnectivityStatus::Other
108 } else {
109 ConnectivityStatus::Global
110 }
111 }
112 }
113}
114
115pub fn to_verifying_key(key: iroh_base::PublicKey) -> p2panda_core::VerifyingKey {
117 p2panda_core::VerifyingKey::from_bytes(key.as_bytes()).expect("already validated public key")
118}
119
120pub fn from_verifying_key(key: p2panda_core::VerifyingKey) -> iroh_base::PublicKey {
122 iroh_base::PublicKey::from_bytes(key.as_bytes()).expect("already validated public key")
123}
124
125pub fn from_signing_key(key: p2panda_core::SigningKey) -> iroh_base::SecretKey {
127 iroh_base::SecretKey::from_bytes(key.as_bytes())
128}
129
130#[cfg(test)]
131mod tests {
132 use super::ConnectivityStatus;
133
134 #[test]
135 fn order() {
136 assert!(ConnectivityStatus::Global > ConnectivityStatus::Local);
137 assert!(ConnectivityStatus::Local > ConnectivityStatus::Other);
138 }
139}