Abstracting over mutable and immutable references

⚓ Rust    📅 2025-11-23    👤 surdeus    👁️ 10      

surdeus

Hey, Rust beginner here. I'm trying to build a simple database in Rust and am currently working on implementing an on-disk B+-tree index. I have an in-memory representation of disk contents like so:


pub struct Page {
    data: Box<[u8]>,
}

impl Page {
    pub fn new() -> Self {
        Self {
            data: Box::new([0u8; config::PAGE_SIZE]),
        }
    }

    pub fn data(&self) -> &[u8] {
        &self.data.0
    }

    pub fn data_mut(&mut self) -> &mut [u8] {
        &mut self.data.0
    }
}

I can't take ownership of this Page struct because another component (the buffer pool) owns it. I can only access the data through read and write guards that return read-only and writable references, like so:

pub trait Guard {
    fn page(&self) -> &Page;
}

pub trait GuardMut: Guard {
    fn page_mut(&mut self) -> &mut Page;
}

Now I want to wrap this page struct into specific page implementations like BtreePage or HeapPage and add the corresponding behavior to each. What is the idiomatic way of achieving that? Do I create two separate structures like BtreePageRefView and BtreePageMutView, or introduce some generic P that I can later bound to Borrow<Page> or BorrowMut<Page>, or maybe go unsafe and just cast it to some struct on which I can define my methods and not worry about the ref/mut separation? I would appreciate any advice on this, as I'm a Rust beginner and trying to wrap my head around designs like this. Thank you!

2 posts - 2 participants

Read full topic

🏷️ Rust_feed