在没有堆的嵌入式设备上,我想解析输入数据并将找到的结果存储在输出切片中。我有一个阅读器,它允许我获取当前可用的数据和一个解析器,它将输入数据与预期的格式相匹配,并将结果存储在Parsed::Value
s 的切片中,该切片可能包含对输入数据的引用。
由于 Rust 编译器发现可能存在对输入数据的引用,因此我不能多次更改数据缓冲区。由于我可以通过手动将输出切片重置为 来确保不再有引用Parsed::Unused
,我认为重用缓冲区应该是安全的。如何在循环的每次迭代中改变输入缓冲区?
以下是我的最小示例,它说明了我的问题:
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`