chat_ui_components/
transport_utils.rs

1/// Return an emoji and transport keyword for a multiaddr string.
2///
3/// Emoji table:
4/// | Transport      | Emoji |
5/// |----------------|-------|
6/// | webrtc-direct  | 🌐    |
7/// | webrtc (circuit) | 🌐  |
8/// | webtransport   | πŸš€    |
9/// | websocket (wss)| πŸ•ΈοΈ    |
10/// | tcp            | πŸ”Œ    |
11/// | quic           | ⚑    |
12/// | p2p-circuit    | πŸ”„    |
13/// | unknown        | ❓    |
14///
15/// For circuit-relay addresses the *final* transport (after the relay hop) is
16/// reported so the UI shows how the target peer is reachable, not how the
17/// relay is reached.
18pub fn get_transport_info(addr: &str) -> (&'static str, &'static str) {
19    // Circuit-relay addresses may contain an underlying transport name
20    // (e.g. webtransport to the relay). We only want to report the
21    // direct peer transport, not the hop to the relay.
22    if let Some(circuit_pos) = addr.find("p2p-circuit") {
23        if let Some(webrtc_pos) = addr.find("webrtc")
24            && webrtc_pos > circuit_pos
25        {
26            return ("🌐", "webrtc");
27        }
28        if let Some(wt_pos) = addr.find("webtransport")
29            && wt_pos > circuit_pos
30        {
31            return ("πŸš€", "webtransport");
32        }
33        return ("πŸ”„", "p2p-circuit");
34    }
35
36    if addr.contains("webrtc-direct") {
37        ("🌐", "webrtc-direct")
38    } else if addr.contains("webrtc") {
39        ("🌐", "webrtc")
40    } else if addr.contains("webtransport") {
41        ("πŸš€", "webtransport")
42    } else if addr.contains("wss") || addr.contains("ws") {
43        ("πŸ•ΈοΈ", "websocket")
44    } else if addr.contains("tcp") {
45        ("πŸ”Œ", "tcp")
46    } else if addr.contains("quic") {
47        ("⚑", "quic")
48    } else {
49        ("❓", "unknown")
50    }
51}
52
53/// Return an emoji representing the transport used in a multiaddr string.
54pub fn get_transport_emoji(addr: &str) -> &'static str {
55    get_transport_info(addr).0
56}
57
58/// Whether a multiaddr string contains at least one transport protocol.
59/// Used to reject bare `/p2p/<peer_id>` addresses that have no value for
60/// display or dialing.
61pub fn addr_has_transport(addr: &str) -> bool {
62    addr.contains("webrtc")
63        || addr.contains("webtransport")
64        || addr.contains("p2p-circuit")
65        || addr.contains("wss")
66        || addr.contains("ws")
67        || addr.contains("tcp")
68        || addr.contains("udp")
69        || addr.contains("quic")
70        || addr.contains("ip4")
71        || addr.contains("ip6")
72        || addr.contains("dns4")
73        || addr.contains("dns6")
74        || addr.contains("dns")
75}
76
77/// Map a transport name (e.g. `"webrtc"`, `"tcp"`) to its display emoji and title.
78pub fn transport_name_to_info(name: &str) -> (&'static str, &'static str) {
79    match name {
80        "webrtc-direct" => ("🌐", "webrtc-direct"),
81        "webrtc" => ("🌐", "webrtc"),
82        "webtransport" => ("πŸš€", "webtransport"),
83        "websocket" => ("πŸ•ΈοΈ", "websocket"),
84        "tcp" => ("πŸ”Œ", "tcp"),
85        "quic" => ("⚑", "quic"),
86        "p2p-circuit" => ("πŸ”„", "p2p-circuit"),
87        _ => ("❓", "unknown"),
88    }
89}