const fn is_newer_16(value: u16, prev_value: u16) -> bool {
const BREAKPOINT: u16 = (u16::MAX >> 1) + 1;
match value.wrapping_sub(prev_value) {
1..BREAKPOINT => true,
BREAKPOINT => value > prev_value,
_ => false,
}
}
const fn is_newer_32(value: u32, prev_value: u32) -> bool {
const BREAKPOINT: u32 = (u32::MAX >> 1) + 1;
match value.wrapping_sub(prev_value) {
1..BREAKPOINT => true,
BREAKPOINT => value > prev_value,
_ => false,
}
}
pub const fn is_newer_sequence_number(sequence_number: u16, prev_sequence_number: u16) -> bool {
is_newer_16(sequence_number, prev_sequence_number)
}
pub const fn is_newer_timestamp(timestamp: u32, prev_timestamp: u32) -> bool {
is_newer_32(timestamp, prev_timestamp)
}
pub const fn latest_sequence_number(sequence_number1: u16, sequence_number2: u16) -> u16 {
if is_newer_sequence_number(sequence_number1, sequence_number2) {
sequence_number1
} else {
sequence_number2
}
}
pub const fn latest_timestamp(timestamp1: u32, timestamp2: u32) -> u32 {
if is_newer_timestamp(timestamp1, timestamp2) {
timestamp1
} else {
timestamp2
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn is_newer_sequence_number_equal() {
assert!(!is_newer_sequence_number(0x0001, 0x0001));
}
#[test]
fn is_newer_sequence_number_no_wrap() {
assert!(is_newer_sequence_number(0xFFFF, 0xFFFE));
assert!(is_newer_sequence_number(0x0001, 0x0000));
assert!(is_newer_sequence_number(0x0100, 0x00FF));
}
#[test]
fn is_newer_sequence_number_forward_wrap() {
assert!(is_newer_sequence_number(0x0000, 0xFFFF));
assert!(is_newer_sequence_number(0x0000, 0xFF00));
assert!(is_newer_sequence_number(0x00FF, 0xFFFF));
assert!(is_newer_sequence_number(0x00FF, 0xFF00));
}
#[test]
fn is_newer_sequence_number_backward_wrap() {
assert!(!is_newer_sequence_number(0xFFFF, 0x0000));
assert!(!is_newer_sequence_number(0xFF00, 0x0000));
assert!(!is_newer_sequence_number(0xFFFF, 0x00FF));
assert!(!is_newer_sequence_number(0xFF00, 0x00FF));
}
#[test]
fn is_newer_sequence_number_half_way_apart() {
assert!(is_newer_sequence_number(0x8000, 0x0000));
assert!(!is_newer_sequence_number(0x0000, 0x8000));
}
#[test]
fn is_newer_timestamp_equal() {
assert!(!is_newer_timestamp(0x00000001, 0x000000001));
}
#[test]
fn is_newer_timestamp_no_wrap() {
assert!(is_newer_timestamp(0xFFFFFFFF, 0xFFFFFFFE));
assert!(is_newer_timestamp(0x00000001, 0x00000000));
assert!(is_newer_timestamp(0x00010000, 0x0000FFFF));
}
#[test]
fn is_newer_timestamp_forward_wrap() {
assert!(is_newer_timestamp(0x00000000, 0xFFFFFFFF));
assert!(is_newer_timestamp(0x00000000, 0xFFFF0000));
assert!(is_newer_timestamp(0x0000FFFF, 0xFFFFFFFF));
assert!(is_newer_timestamp(0x0000FFFF, 0xFFFF0000));
}
#[test]
fn is_newer_timestamp_backward_wrap() {
assert!(!is_newer_timestamp(0xFFFFFFFF, 0x00000000));
assert!(!is_newer_timestamp(0xFFFF0000, 0x00000000));
assert!(!is_newer_timestamp(0xFFFFFFFF, 0x0000FFFF));
assert!(!is_newer_timestamp(0xFFFF0000, 0x0000FFFF));
}
#[test]
fn is_newer_timestamp_half_way_apart() {
assert!(is_newer_timestamp(0x80000000, 0x00000000));
assert!(!is_newer_timestamp(0x00000000, 0x80000000));
}
#[test]
fn latest_sequence_number_no_wrap() {
assert_eq!(0xFFFF, latest_sequence_number(0xFFFF, 0xFFFE));
assert_eq!(0x0001, latest_sequence_number(0x0001, 0x0000));
assert_eq!(0x0100, latest_sequence_number(0x0100, 0x00FF));
assert_eq!(0xFFFF, latest_sequence_number(0xFFFE, 0xFFFF));
assert_eq!(0x0001, latest_sequence_number(0x0000, 0x0001));
assert_eq!(0x0100, latest_sequence_number(0x00FF, 0x0100));
}
#[test]
fn latest_sequence_number_wrap() {
assert_eq!(0x0000, latest_sequence_number(0x0000, 0xFFFF));
assert_eq!(0x0000, latest_sequence_number(0x0000, 0xFF00));
assert_eq!(0x00FF, latest_sequence_number(0x00FF, 0xFFFF));
assert_eq!(0x00FF, latest_sequence_number(0x00FF, 0xFF00));
assert_eq!(0x0000, latest_sequence_number(0xFFFF, 0x0000));
assert_eq!(0x0000, latest_sequence_number(0xFF00, 0x0000));
assert_eq!(0x00FF, latest_sequence_number(0xFFFF, 0x00FF));
assert_eq!(0x00FF, latest_sequence_number(0xFF00, 0x00FF));
}
#[test]
fn latest_timestamp_no_wrap() {
assert_eq!(0xFFFFFFFF, latest_timestamp(0xFFFFFFFF, 0xFFFFFFFE));
assert_eq!(0x00000001, latest_timestamp(0x00000001, 0x00000000));
assert_eq!(0x00010000, latest_timestamp(0x00010000, 0x0000FFFF));
}
#[test]
fn latest_timestamp_wrap() {
assert_eq!(0x00000000, latest_timestamp(0x00000000, 0xFFFFFFFF));
assert_eq!(0x00000000, latest_timestamp(0x00000000, 0xFFFF0000));
assert_eq!(0x0000FFFF, latest_timestamp(0x0000FFFF, 0xFFFFFFFF));
assert_eq!(0x0000FFFF, latest_timestamp(0x0000FFFF, 0xFFFF0000));
assert_eq!(0x00000000, latest_timestamp(0xFFFFFFFF, 0x00000000));
assert_eq!(0x00000000, latest_timestamp(0xFFFF0000, 0x00000000));
assert_eq!(0x0000FFFF, latest_timestamp(0xFFFFFFFF, 0x0000FFFF));
assert_eq!(0x0000FFFF, latest_timestamp(0xFFFF0000, 0x0000FFFF));
}
}