#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum NativePeerSendOrder {
OptionalTransportsFirst,
IrohFirstAllowOptionalFallback,
}
pub(crate) fn peer_send_order(
active_transport: Option<&str>,
iroh_transport: Option<&str>,
) -> NativePeerSendOrder {
if active_transport
.map(crate::transport_label::is_optional)
.unwrap_or(false)
{
return NativePeerSendOrder::OptionalTransportsFirst;
}
if iroh_transport
.map(crate::transport_label::is_direct_iroh)
.unwrap_or(false)
|| active_transport
.map(crate::transport_label::is_direct_iroh)
.unwrap_or(false)
{
return NativePeerSendOrder::IrohFirstAllowOptionalFallback;
}
NativePeerSendOrder::OptionalTransportsFirst
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct TransportPolicyVectors {
send_order: Vec<SendOrderVector>,
}
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct SendOrderVector {
active_transport: Option<String>,
iroh_transport: Option<String>,
order: String,
}
fn parse_order(value: &str) -> NativePeerSendOrder {
match value {
"optionalTransportsFirst" => NativePeerSendOrder::OptionalTransportsFirst,
"irohFirstAllowOptionalFallback" => NativePeerSendOrder::IrohFirstAllowOptionalFallback,
other => panic!("unknown send-order vector: {other}"),
}
}
#[test]
fn active_optional_transport_stays_first() {
assert_eq!(
peer_send_order(Some("webrtc"), Some("iroh-quic")),
NativePeerSendOrder::OptionalTransportsFirst
);
assert_eq!(
peer_send_order(Some("moq"), Some("iroh-lan")),
NativePeerSendOrder::OptionalTransportsFirst
);
}
#[test]
fn direct_iroh_paths_are_primary() {
assert_eq!(
peer_send_order(Some("iroh-quic"), Some("iroh-quic")),
NativePeerSendOrder::IrohFirstAllowOptionalFallback
);
assert_eq!(
peer_send_order(Some("iroh-lan"), Some("iroh-lan")),
NativePeerSendOrder::IrohFirstAllowOptionalFallback
);
assert_eq!(
peer_send_order(Some("ble"), Some("ble")),
NativePeerSendOrder::IrohFirstAllowOptionalFallback
);
}
#[test]
fn relay_or_unknown_paths_probe_optional_transports_first() {
assert_eq!(
peer_send_order(Some("iroh-relay"), Some("iroh-relay")),
NativePeerSendOrder::OptionalTransportsFirst
);
assert_eq!(
peer_send_order(Some("iroh"), Some("iroh")),
NativePeerSendOrder::OptionalTransportsFirst
);
assert_eq!(
peer_send_order(None, None),
NativePeerSendOrder::OptionalTransportsFirst
);
}
#[test]
fn matches_shared_transport_policy_vectors() {
let vectors: TransportPolicyVectors =
serde_json::from_str(include_str!("../testdata/transport_policy_vectors.json"))
.expect("transport policy vectors");
for vector in vectors.send_order {
assert_eq!(
peer_send_order(
vector.active_transport.as_deref(),
vector.iroh_transport.as_deref()
),
parse_order(&vector.order),
"active={:?} iroh={:?}",
vector.active_transport,
vector.iroh_transport
);
}
}
}