use std::net::{IpAddr, SocketAddr};
use p2panda_core::Topic;
use crate::NodeId;
pub trait ShortFormat {
fn fmt_short(&self) -> String;
}
impl ShortFormat for NodeId {
fn fmt_short(&self) -> String {
self.to_hex()[0..10].to_string()
}
}
impl ShortFormat for iroh_base::EndpointId {
fn fmt_short(&self) -> String {
self.to_string()[0..10].to_string()
}
}
impl ShortFormat for [u8; 32] {
fn fmt_short(&self) -> String {
hex::encode(&self[0..5]).to_string()
}
}
impl ShortFormat for Topic {
fn fmt_short(&self) -> String {
self.to_string()[0..10].to_string()
}
}
impl ShortFormat for Vec<u8> {
fn fmt_short(&self) -> String {
hex::encode(&self[0..5]).to_string()
}
}
impl ShortFormat for Vec<NodeId> {
fn fmt_short(&self) -> String {
let list: Vec<String> = self.iter().map(|addr| addr.fmt_short()).collect();
format!("[{}]", list.join(", "))
}
}
impl ShortFormat for Vec<iroh_base::EndpointId> {
fn fmt_short(&self) -> String {
let list: Vec<String> = self
.iter()
.map(|addr| addr.fmt_short().to_string())
.collect();
format!("[{}]", list.join(", "))
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum ConnectivityStatus {
Other,
Local,
Global,
}
impl ConnectivityStatus {
pub fn is_global(&self) -> bool {
self == &ConnectivityStatus::Global
}
}
pub fn connectivity_status(addr: &SocketAddr) -> ConnectivityStatus {
match addr.ip() {
IpAddr::V4(ip) => {
if ip.is_loopback() || ip.is_link_local() || ip.is_private() {
ConnectivityStatus::Local
} else if ip.is_multicast()
|| ip.is_broadcast()
|| ip.is_documentation()
|| ip.is_unspecified()
{
ConnectivityStatus::Other
} else {
ConnectivityStatus::Global
}
}
IpAddr::V6(ip) => {
if ip.is_loopback() || ip.is_unique_local() || ip.is_unicast_link_local() {
ConnectivityStatus::Local
} else if ip.is_multicast() || ip.is_unspecified() {
ConnectivityStatus::Other
} else {
ConnectivityStatus::Global
}
}
}
}
pub fn to_verifying_key(key: iroh_base::PublicKey) -> p2panda_core::VerifyingKey {
p2panda_core::VerifyingKey::from_bytes(key.as_bytes()).expect("already validated public key")
}
pub fn from_verifying_key(key: p2panda_core::VerifyingKey) -> iroh_base::PublicKey {
iroh_base::PublicKey::from_bytes(key.as_bytes()).expect("already validated public key")
}
pub fn from_signing_key(key: p2panda_core::SigningKey) -> iroh_base::SecretKey {
iroh_base::SecretKey::from_bytes(key.as_bytes())
}
#[cfg(test)]
mod tests {
use super::ConnectivityStatus;
#[test]
fn order() {
assert!(ConnectivityStatus::Global > ConnectivityStatus::Local);
assert!(ConnectivityStatus::Local > ConnectivityStatus::Other);
}
}