openrtc 1.0.4

OpenRTC: a Rust-first P2P runtime for device discovery, signaling, and iroh/QUIC networking.
Documentation
//! Canonical transport label taxonomy.
//!
//! Peer snapshots, native send routing, and optional transport projection all
//! exchange labels as strings across Rust, WASM, TS, and IPC. Keep normalization
//! and classification in one target-neutral place so cross-platform behavior
//! cannot drift one call site at a time.

use crate::route_policy::{KnownRoute, RouteFamily, RouteLocality};

pub(crate) const IROH: &str = KnownRoute::Iroh.as_str();
pub(crate) const IROH_QUIC: &str = KnownRoute::IrohQuic.as_str();
pub(crate) const IROH_RELAY: &str = KnownRoute::IrohRelay.as_str();
pub(crate) const IROH_LAN: &str = KnownRoute::IrohLan.as_str();
pub(crate) const BLE: &str = KnownRoute::Ble.as_str();
pub(crate) const WEBRTC: &str = KnownRoute::WebRtc.as_str();
pub(crate) const WEBRTC_LAN: &str = KnownRoute::WebRtcLan.as_str();
pub(crate) const WEBRTC_TURN: &str = KnownRoute::WebRtcTurn.as_str();
pub(crate) const MOQ: &str = KnownRoute::Moq.as_str();

pub(crate) fn normalize(value: &str) -> Option<&'static str> {
    crate::route_policy::normalize_route(value).map(KnownRoute::as_str)
}

#[allow(dead_code)]
pub(crate) fn is_iroh_base(value: &str) -> bool {
    crate::route_policy::normalize_route(value)
        .map(|route| route.descriptor().base_protocol == IROH)
        .unwrap_or(false)
}

#[allow(dead_code)]
pub(crate) fn is_direct_iroh(value: &str) -> bool {
    crate::route_policy::normalize_route(value)
        .map(|route| {
            let descriptor = route.descriptor();
            descriptor.base_protocol == IROH
                && matches!(
                    descriptor.locality,
                    RouteLocality::Nearby | RouteLocality::DirectInternet
                )
        })
        .unwrap_or(false)
}

#[allow(dead_code)]
pub(crate) fn is_optional(value: &str) -> bool {
    crate::route_policy::normalize_route(value)
        .map(|route| route.descriptor().family == RouteFamily::OptionalRoute)
        .unwrap_or(false)
}

#[allow(dead_code)]
pub(crate) fn is_webrtc(value: &str) -> bool {
    crate::route_policy::normalize_route(value)
        .map(|route| route.descriptor().base_protocol == WEBRTC)
        .unwrap_or(false)
}

pub(crate) fn is_independent_transport(value: &str) -> bool {
    crate::route_policy::normalize_route(value)
        .map(|route| route.descriptor().independently_instantiable)
        .unwrap_or(false)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[derive(serde::Deserialize)]
    #[serde(rename_all = "camelCase")]
    struct TransportPolicyVectors {
        labels: Vec<LabelVector>,
    }

    #[derive(serde::Deserialize)]
    #[serde(rename_all = "camelCase")]
    struct LabelVector {
        input: String,
        normalized: Option<String>,
        iroh_base: bool,
        direct_iroh: bool,
        optional: bool,
        web_rtc: bool,
        independent: bool,
    }

    #[test]
    fn normalizes_official_labels_case_insensitively() {
        for (input, expected) in [
            ("iroh", IROH),
            (" IROH-QUIC ", IROH_QUIC),
            ("iroh-relay", IROH_RELAY),
            ("iroh-lan", IROH_LAN),
            ("ble", BLE),
            ("webrtc", WEBRTC),
            ("webrtc-lan", WEBRTC_LAN),
            ("webrtc-turn", WEBRTC_TURN),
            ("moq", MOQ),
        ] {
            assert_eq!(normalize(input), Some(expected));
        }
        assert_eq!(normalize("lan"), None);
        assert_eq!(normalize("webtransport"), None);
    }

    #[test]
    fn classifies_transport_families() {
        assert!(is_iroh_base(IROH));
        assert!(is_iroh_base(IROH_QUIC));
        assert!(is_iroh_base(IROH_LAN));
        assert!(is_iroh_base(IROH_RELAY));
        assert!(is_iroh_base(BLE));
        assert!(!is_iroh_base(WEBRTC));

        assert!(is_direct_iroh(IROH_QUIC));
        assert!(is_direct_iroh(IROH_LAN));
        assert!(is_direct_iroh(BLE));
        assert!(!is_direct_iroh(IROH_RELAY));

        assert!(is_optional(WEBRTC));
        assert!(is_optional(WEBRTC_LAN));
        assert!(is_optional(WEBRTC_TURN));
        assert!(is_optional(MOQ));
        assert!(!is_optional(IROH_QUIC));

        assert!(is_webrtc(WEBRTC));
        assert!(is_webrtc(WEBRTC_LAN));
        assert!(is_webrtc(WEBRTC_TURN));
        assert!(!is_webrtc(MOQ));

        assert!(is_independent_transport(WEBRTC));
        assert!(is_independent_transport(MOQ));
        assert!(!is_independent_transport(WEBRTC_LAN));
    }

    #[test]
    fn matches_shared_transport_policy_vectors() {
        let vectors: TransportPolicyVectors =
            serde_json::from_str(crate::generated::route_registry::TRANSPORT_REGISTRY_JSON)
                .expect("transport policy vectors");
        for vector in vectors.labels {
            assert_eq!(
                normalize(&vector.input),
                vector.normalized.as_deref(),
                "normalize({:?})",
                vector.input
            );
            assert_eq!(
                is_iroh_base(&vector.input),
                vector.iroh_base,
                "is_iroh_base({:?})",
                vector.input
            );
            assert_eq!(
                is_direct_iroh(&vector.input),
                vector.direct_iroh,
                "is_direct_iroh({:?})",
                vector.input
            );
            assert_eq!(
                is_optional(&vector.input),
                vector.optional,
                "is_optional({:?})",
                vector.input
            );
            assert_eq!(
                is_webrtc(&vector.input),
                vector.web_rtc,
                "is_webrtc({:?})",
                vector.input
            );
            assert_eq!(
                is_independent_transport(&vector.input),
                vector.independent,
                "is_independent_transport({:?})",
                vector.input
            );
        }
    }
}