How to return immutable reference to underlying immutable data from mutable Cursor object?

I have a simple cursor object:

pub struct Cursor<'a> {                                                                                                                                                                                                        
    pub data: &'a [u8],                                                                                                                                                                                                                          
}                                                                                                                                                                                                                                                

which tracks my reading through an underlying immutable u8 slice. I want to be able to read a number of bytes and return them as slice, while advancing data in the cursor object:

fn read(&mut self, len: usize) -> Result<&[u8], &'static str> {                                                                                                                                                                              
    let (bytes, rest) = self.data.split_at(len);                                                                                                                                                                                             
    self.data = rest;                                                                                                                                                                                                                        
    Ok(bytes)                                                                                                                                                                                                                                
}                                                                                                                                                                                                                                            

The returned slice shares an immutable borrow of the underlying slice with the cursor object, which should be ok, but rust thinks that the returned slice still borrows the cursor object. Is there a way to declared that the returned slice doesn't borrow the cursor object even though they share the same lifetime?

What you should do is change the signature of read into.

fn read(&mut self, len: usize) -> Result<&'a [u8], &'static str> {                                                                                                                                                                              
    let (bytes, rest) = self.data.split_at(len);                                                                                                                                                                                             
    self.data = rest;                                                                                                                                                                                                                        
    Ok(bytes)                                                                                                                                                                                                                                
}              

Notice the additional 'a, which means returned slice is borrowed from original data instead of the cursor.

3 Likes

That was it, thanks very much!