use super::bridge_protocol::{BridgeRejectionCause, BridgeRejectionClass};
pub(super) fn should_fall_back_to_bind(cause: BridgeRejectionCause) -> bool {
matches!(
cause.class(),
BridgeRejectionClass::RecoverableBySupervisorRebind
)
}
#[cfg(test)]
#[allow(clippy::panic, clippy::unwrap_used, clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn falls_back_on_recoverable_class() {
assert!(should_fall_back_to_bind(BridgeRejectionCause::NotBound));
assert!(should_fall_back_to_bind(
BridgeRejectionCause::StaleSupervisor
));
assert!(should_fall_back_to_bind(
BridgeRejectionCause::SenderMismatch
));
}
#[test]
fn does_not_fall_back_on_fatal_class() {
let fatal = [
BridgeRejectionCause::AlreadyBound,
BridgeRejectionCause::InvalidBootstrapToken,
BridgeRejectionCause::UnsupportedProtocolVersion,
BridgeRejectionCause::InvalidSupervisorSpec,
BridgeRejectionCause::InvalidPeerSpec,
BridgeRejectionCause::AddressMismatch,
BridgeRejectionCause::Unsupported,
BridgeRejectionCause::Internal,
];
for cause in fatal {
assert!(
!should_fall_back_to_bind(cause),
"cause {cause:?} must not trigger bind fallback"
);
}
}
#[test]
fn class_partitions_causes_cleanly() {
let recoverable = [
BridgeRejectionCause::NotBound,
BridgeRejectionCause::StaleSupervisor,
BridgeRejectionCause::SenderMismatch,
];
for cause in recoverable {
assert_eq!(
cause.class(),
BridgeRejectionClass::RecoverableBySupervisorRebind,
"cause {cause:?} must be in the recoverable class"
);
}
let fatal = [
BridgeRejectionCause::AlreadyBound,
BridgeRejectionCause::InvalidBootstrapToken,
BridgeRejectionCause::UnsupportedProtocolVersion,
BridgeRejectionCause::InvalidSupervisorSpec,
BridgeRejectionCause::InvalidPeerSpec,
BridgeRejectionCause::AddressMismatch,
BridgeRejectionCause::Unsupported,
BridgeRejectionCause::Internal,
];
for cause in fatal {
assert_eq!(
cause.class(),
BridgeRejectionClass::Fatal,
"cause {cause:?} must be in the fatal class"
);
}
}
}