use std::cmp::Ordering;
use super::{BoundsCheck, BoundsStatus, Index, Length, PositionStatus};
impl BoundsCheck<Length> for Index {
fn check_overflows(&self, length: Length) -> BoundsStatus {
let this = *self;
let other = length.convert_to_index() ;
if this > other {
BoundsStatus::Overflowed
} else {
BoundsStatus::Within
}
}
fn check_content_position(&self, content_length: Length) -> PositionStatus {
let this = *self;
let length = content_length.as_usize();
match this.as_usize().cmp(&length) {
Ordering::Less => PositionStatus::Within,
Ordering::Equal => PositionStatus::Boundary,
Ordering::Greater => PositionStatus::Beyond,
}
}
}
impl BoundsCheck<Index> for Index {
fn check_overflows(&self, other: Index) -> BoundsStatus {
let this = *self;
if this > other {
BoundsStatus::Overflowed
} else {
BoundsStatus::Within
}
}
fn check_content_position(&self, content_length: Index) -> PositionStatus {
let this = *self;
let length = content_length.as_usize();
match this.as_usize().cmp(&length) {
Ordering::Less => PositionStatus::Within,
Ordering::Equal => PositionStatus::Boundary,
Ordering::Greater => PositionStatus::Beyond,
}
}
}
#[cfg(test)]
mod tests_check_overflows {
use super::*;
use crate::{idx, len};
#[test]
fn test_index_bounds_check_length() {
let length = len(10);
let index = idx(0);
assert_eq!(index.check_overflows(length), BoundsStatus::Within);
let index = idx(9);
assert_eq!(index.check_overflows(length), BoundsStatus::Within);
let index = idx(10);
assert_eq!(index.check_overflows(length), BoundsStatus::Overflowed);
let index = idx(11);
assert_eq!(index.check_overflows(length), BoundsStatus::Overflowed);
}
#[test]
fn test_index_bounds_check_index() {
let index2 = idx(10);
let index1 = idx(0);
assert_eq!(index1.check_overflows(index2), BoundsStatus::Within);
let index1 = idx(9);
assert_eq!(index1.check_overflows(index2), BoundsStatus::Within);
let index1 = idx(10);
assert_eq!(index1.check_overflows(index2), BoundsStatus::Within);
let index1 = idx(11);
assert_eq!(index1.check_overflows(index2), BoundsStatus::Overflowed);
}
#[test]
fn test_index_bounds_check_zero_length() {
let length = len(0);
let index = idx(0);
assert_eq!(index.check_overflows(length), BoundsStatus::Within);
let index = idx(1);
assert_eq!(index.check_overflows(length), BoundsStatus::Overflowed);
}
#[test]
fn test_index_bounds_check_zero_index() {
let index2 = idx(0);
let index1 = idx(0);
assert_eq!(index1.check_overflows(index2), BoundsStatus::Within);
let index1 = idx(1);
assert_eq!(index1.check_overflows(index2), BoundsStatus::Overflowed);
}
}
#[cfg(test)]
mod tests_check_content_position {
use super::*;
use crate::{idx, len};
#[test]
fn test_index_content_position_check_length() {
let length = len(5);
let index = idx(0);
assert_eq!(index.check_content_position(length), PositionStatus::Within);
let index = idx(2);
assert_eq!(index.check_content_position(length), PositionStatus::Within);
let index = idx(4);
assert_eq!(index.check_content_position(length), PositionStatus::Within);
let index = idx(5);
assert_eq!(
index.check_content_position(length),
PositionStatus::Boundary
);
let index = idx(6);
assert_eq!(index.check_content_position(length), PositionStatus::Beyond);
let index = idx(10);
assert_eq!(index.check_content_position(length), PositionStatus::Beyond);
}
#[test]
fn test_index_content_position_vs_array_position() {
let length = len(3);
let index = idx(2);
assert_eq!(index.check_content_position(length), PositionStatus::Within);
let boundary_index = idx(3);
assert_eq!(
boundary_index.check_content_position(length),
PositionStatus::Boundary
);
}
#[test]
fn test_index_content_position_check_zero_length() {
let length = len(0);
let index = idx(0);
assert_eq!(
index.check_content_position(length),
PositionStatus::Boundary
);
let index = idx(1);
assert_eq!(index.check_content_position(length), PositionStatus::Beyond);
}
}