1use core::num::{NonZeroU8, NonZeroUsize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
8pub struct PageSize(NonZeroU8);
9
10impl PageSize {
11 pub const fn from_log2(shift: u8) -> Self {
13 assert!(shift > 0 && (shift as u32) < usize::BITS);
14 Self(unsafe { NonZeroU8::new_unchecked(shift) })
16 }
17
18 pub const fn bytes(&self) -> usize {
20 1usize << self.0.get()
21 }
22
23 #[inline]
25 pub const fn log2(self) -> u8 {
26 self.0.get()
27 }
28
29 #[inline]
32 pub const fn total_bytes(self, count: NonZeroUsize) -> Option<usize> {
33 self.bytes().checked_mul(count.get())
34 }
35
36 #[inline]
38 pub const fn is_aligned(self, addr: usize) -> bool {
39 addr & (self.bytes() - 1) == 0
40 }
41
42 #[inline]
44 pub const fn align_down(self, addr: usize) -> usize {
45 addr & !(self.bytes() - 1)
46 }
47
48 #[inline]
51 pub const fn align_up(self, addr: usize) -> Option<usize> {
52 let mask = self.bytes() - 1;
53 match addr.checked_add(mask) {
54 Some(a) => Some(a & !mask),
55 None => None,
56 }
57 }
58}