1use codec::{ConstEncodedLen, Decode, Encode, MaxEncodedLen};
2use jam_types::{Segment, SEGMENT_LEN};
3
4pub const PAGE_SIZE: u64 = 4096;
6
7#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode, MaxEncodedLen)]
9pub struct PageAddr(pub u64);
10
11impl core::fmt::Debug for PageAddr {
12 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
13 let page = self.0 / PAGE_SIZE;
14 write!(f, "{page}/{:#x}", self.0)
15 }
16}
17
18impl core::fmt::Display for PageAddr {
19 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
20 core::fmt::Debug::fmt(self, f)
21 }
22}
23
24impl ConstEncodedLen for PageAddr {}
25
26pub trait PageSegmentOps {
33 fn page(&self) -> &[u8];
35
36 fn page_mut(&mut self) -> &mut [u8];
38
39 fn page_address(&self) -> u64;
41
42 fn set_page_address(&mut self, address: u64);
44}
45
46impl PageSegmentOps for [u8] {
47 fn page(&self) -> &[u8] {
48 debug_assert_eq!(SEGMENT_LEN, self.len());
49 &self[..PAGE_SIZE as usize]
50 }
51
52 fn page_mut(&mut self) -> &mut [u8] {
53 debug_assert_eq!(SEGMENT_LEN, self.len());
54 &mut self[..PAGE_SIZE as usize]
55 }
56
57 fn page_address(&self) -> u64 {
58 debug_assert_eq!(SEGMENT_LEN, self.len());
59 let a = &self[PAGE_SIZE as usize..];
60 u64::from_le_bytes([a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]])
61 }
62
63 fn set_page_address(&mut self, address: u64) {
64 debug_assert_eq!(SEGMENT_LEN, self.len());
65 self[PAGE_SIZE as usize..].copy_from_slice(&address.to_le_bytes()[..]);
66 }
67}
68
69impl PageSegmentOps for Segment {
70 fn page(&self) -> &[u8] {
71 self.as_ref().page()
72 }
73
74 fn page_mut(&mut self) -> &mut [u8] {
75 self.as_mut().page_mut()
76 }
77
78 fn page_address(&self) -> u64 {
79 self.as_ref().page_address()
80 }
81
82 fn set_page_address(&mut self, address: u64) {
83 self.as_mut().set_page_address(address)
84 }
85}