I’m trying to add context to one of my errors by adding a reference to an enum case returned from a function
fn read_line<'a>(&mut self, buf: &'a mut [u8]) -> Result<(), ParseError<'a>>. Doing so causes the calling method to fail to compile with E0499 due to borrowing
buf as mutable more than once and I’m struggling to see why.
I’ve minimally reproduced the issue in https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=9e26a77fec781442bea087b8c6953c0a.
What I’m trying to do is read bytes from the
&mut Read and store them in
&mut buf. In practice this is a
#![no_std] crate so I can’t allocate.
buf is a stack allocated buffer passed to my modem driver for it to store Hayes AT command responses in and
&mut Read is a backed by a ring buffer serviced by a hardware UART interrupt.
The parser reads line by line and stops once it hits a terminating line (
ERROR etc). If the final response line isn’t
OK I want to return an
Err(ParseError::Line(the_error_line)) that references bytes from the buffer that was passed in to the parser.
This seems like it should work; the parser receives a borrow and either returns
Ok(offset), no borrows in the value (though there is a borrow in the type, is the entire
Result tagged with
'a?) , or
Err(ParseError<'a>) where the provided mutable borrow should be extended until this returned value is dropped.
I’ve never fully mastered rust lifetimes and am hoping someone can point me in the right direction.