On an embedded device without a heap, I want to parse input data and store the found results in an output slice. I have a reader which allows me to get the currently available data and a parser which matches the input data to the expected format and stores the results in a slice of Parsed::Value
s which could possibly hold references to the input data.
Since the Rust compiler sees that there could be references to the input data, I can not mutate the data buffer more than once. Since I can ensure that there are no references anymore by manually resetting the output slice to Parsed::Unused
, I think that it should be safe to reuse the buffer. How can I achieve to mutate the input buffer in every iteration of the loop?
The following is my minimal example which illustrates my problem:
trait Reader {
fn peek<'a>(&self, data: &'a mut [u8]) -> &'a [u8]; // copy currently available bytes from ringbuffer
fn consume(&self, num: usize); // drop at the head of input queue
}
trait Parser {
fn parse<'a>(&self, input: &'a [u8], parsed_value: &mut [Parsed<'a>]) -> Result<(), ()>;
}
enum Parsed<'a> {
Unused,
Value(&'a [u8]),
}
fn read_and_parse<'a>(
reader: impl Reader,
parser: impl Parser,
data_buffer: &'a mut [u8],
values: &mut [Parsed<'a>],
) {
loop {
for v in values.iter_mut() {
// This block should ensure that no more
*v = Parsed::Unused; // references are held into the buffer
} // used in the previous iteration.
let rx = reader.peek(data_buffer);
if let Ok(()) = parser.parse(rx, values) {
return;
}
reader.consume(1); // this could be replaced with smarter logic how to drop input bytes
}
}
error[E0499]: cannot borrow `*data_buffer` as mutable more than once at a time
--> src/lib.rs:26:30
|
15 | fn read_and_parse<'a>(
| -- lifetime `'a` defined here
...
26 | let rx = reader.peek(data_buffer);
| ------------^^^^^^^^^^^-
| | |
| | mutable borrow starts here in previous iteration of loop
| argument requires that `*data_buffer` is borrowed for `'a`