use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct PageIndex(u32);
impl PageIndex {
pub const FIRST: Self = Self(0);
#[must_use]
pub const fn new(n: u32) -> Self {
Self(n)
}
#[must_use]
pub const fn get(self) -> u32 {
self.0
}
}
impl From<u32> for PageIndex {
fn from(n: u32) -> Self {
Self(n)
}
}
impl From<PageIndex> for u32 {
fn from(index: PageIndex) -> Self {
index.0
}
}
impl fmt::Display for PageIndex {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
#[cfg(test)]
mod tests {
use super::PageIndex;
#[test]
fn from_u32_round_trips_both_ways() {
for n in [0u32, 1, 2, 41, u32::MAX] {
let index = PageIndex::from(n);
assert_eq!(index.get(), n);
assert_eq!(u32::from(index), n);
assert_eq!(index, PageIndex::new(n));
}
}
#[test]
fn display_is_the_bare_zero_based_number() {
assert_eq!(PageIndex::new(0).to_string(), "0");
assert_eq!(PageIndex::new(41).to_string(), "41");
assert_eq!(format!("page {}", PageIndex::new(2)), "page 2");
}
#[test]
fn first_and_default_are_page_zero() {
assert_eq!(PageIndex::FIRST, PageIndex::new(0));
assert_eq!(PageIndex::default(), PageIndex::FIRST);
}
#[test]
fn ordering_is_the_numbers() {
let mut pages = [PageIndex::new(2), PageIndex::new(0), PageIndex::new(1)];
pages.sort_unstable();
assert_eq!(
pages,
[PageIndex::new(0), PageIndex::new(1), PageIndex::new(2)]
);
}
#[test]
fn a_literal_converts_the_way_an_impl_into_argument_needs() {
fn takes(index: impl Into<PageIndex>) -> PageIndex {
index.into()
}
assert_eq!(takes(0), PageIndex::FIRST);
assert_eq!(takes(PageIndex::new(3)), PageIndex::new(3));
}
}