1use crate::{VmMeta, VPN};
2use core::fmt;
3
4#[derive(Clone, Copy)]
6pub struct Pos<Meta: VmMeta> {
7 pub vpn: VPN<Meta>,
9 pub level: usize,
11}
12
13impl<Meta: VmMeta> Pos<Meta> {
14 #[inline]
16 pub const fn new(vpn: VPN<Meta>, level: usize) -> Self {
17 Self { vpn, level }
18 }
19
20 #[inline]
22 pub const fn stop() -> Self {
23 Self {
24 vpn: VPN::ZERO,
25 level: Meta::MAX_LEVEL + 1,
26 }
27 }
28
29 #[inline]
31 pub fn prev(self) -> Self {
32 let delta = match self.level {
33 0 => 1,
34 n => Meta::pages_in_table(n - 1),
35 };
36 match self.vpn.val().checked_sub(delta) {
37 Some(vpn) => Self {
38 vpn: VPN::new(vpn),
39 ..self
40 },
41 None => panic!("prev: vpn overflow"),
42 }
43 }
44
45 #[inline]
47 pub fn next(self) -> Self {
48 let delta = match self.level {
49 0 => 1,
50 n => Meta::pages_in_table(n - 1),
51 };
52 match self.vpn.val().checked_add(delta) {
53 Some(vpn) => Self {
54 vpn: VPN::new(vpn),
55 ..self
56 },
57 None => panic!("next: vpn overflow"),
58 }
59 }
60
61 #[inline]
63 pub fn up(self) -> Self {
64 match self.level.checked_add(1) {
65 Some(level) => Self { level, ..self },
66 None => panic!("up: level overflow"),
67 }
68 }
69
70 #[inline]
72 pub fn down(self) -> Self {
73 match self.level.checked_sub(1) {
74 Some(level) => Self { level, ..self },
75 None => panic!("down: level overflow"),
76 }
77 }
78}
79
80impl<Meta: VmMeta> fmt::Debug for Pos<Meta> {
81 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82 write!(
83 f,
84 "Pos {{ vpn = {:#x}, level = {:#x} }}",
85 self.vpn.val(),
86 self.level
87 )
88 }
89}