use crate::rpc::RpcError;
pub(crate) fn next_cursor_after_batch(
to_block: u64,
logs_empty: bool,
reported_tip: u64,
) -> Result<u64, RpcError> {
if logs_empty && to_block > reported_tip {
return Err(RpcError::CursorPastTip {
to_block,
reported_tip,
});
}
Ok(to_block)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn next_cursor_advances_on_non_empty_batch_regardless_of_tip() {
assert_eq!(next_cursor_after_batch(100, false, 0).unwrap(), 100);
assert_eq!(next_cursor_after_batch(100, false, 50).unwrap(), 100);
assert_eq!(next_cursor_after_batch(100, false, u64::MAX).unwrap(), 100);
}
#[test]
fn next_cursor_advances_on_empty_batch_within_tip() {
assert_eq!(next_cursor_after_batch(100, true, 100).unwrap(), 100);
assert_eq!(next_cursor_after_batch(100, true, 101).unwrap(), 100);
assert_eq!(next_cursor_after_batch(100, true, u64::MAX).unwrap(), 100);
}
#[test]
fn next_cursor_rejects_empty_batch_past_tip() {
match next_cursor_after_batch(100, true, 99) {
Err(RpcError::CursorPastTip {
to_block,
reported_tip,
}) => {
assert_eq!(to_block, 100);
assert_eq!(reported_tip, 99);
}
other => panic!("expected CursorPastTip, got {:?}", other),
}
assert!(next_cursor_after_batch(100, true, 0).is_err());
assert!(next_cursor_after_batch(u64::MAX, true, u64::MAX - 1).is_err());
}
}