#[derive(Debug, Default)]
pub(super) struct SendBatch {
topology_refresh: Turn,
transient_delay: Turn,
}
impl SendBatch {
pub(super) fn claim_topology_refresh(&mut self) -> bool {
self.topology_refresh.claim()
}
pub(super) fn claim_transient_delay(&mut self) -> bool {
self.transient_delay.claim()
}
pub(super) fn end(&mut self) {
*self = Self::default();
}
}
#[derive(Debug, Default)]
struct Turn {
taken: bool,
}
impl Turn {
fn claim(&mut self) -> bool {
!std::mem::replace(&mut self.taken, true)
}
}
#[cfg(test)]
mod tests {
#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
reason = "test code: a panic is how a test reports failure"
)]
use super::SendBatch;
#[test]
fn a_turn_is_granted_once_per_batch() {
let mut batch = SendBatch::default();
assert!(batch.claim_topology_refresh());
assert!(!batch.claim_topology_refresh());
assert!(!batch.claim_topology_refresh());
assert!(batch.claim_transient_delay());
assert!(!batch.claim_transient_delay());
}
#[test]
fn the_two_turns_do_not_consume_each_other() {
let mut batch = SendBatch::default();
assert!(batch.claim_topology_refresh());
assert!(
batch.claim_transient_delay(),
"a reload must not spend the delay"
);
let mut batch = SendBatch::default();
assert!(batch.claim_transient_delay());
assert!(
batch.claim_topology_refresh(),
"a delay must not spend the reload"
);
}
#[test]
fn ending_the_batch_hands_both_turns_back() {
let mut batch = SendBatch::default();
assert!(batch.claim_topology_refresh());
assert!(batch.claim_transient_delay());
batch.end();
assert!(batch.claim_topology_refresh());
assert!(batch.claim_transient_delay());
}
}