I try to write simple decoder, that reads bytes into an internal buffer when needed.
use std::io::{Error, Read};
struct DecodeError;
enum FillError {
Overflow,
Io(Error),
}
struct Decoder {
buffer: Vec<u8>,
read: usize,
write: usize,
}
impl Decoder {
fn decode<'a>(&'a mut self) -> Result<&'a [u8], DecodeError> {
if self.write - self.read > 0 {
let last = self.read;
self.read = self.write;
Ok(&self.buffer[last..self.write])
} else {
Err(DecodeError)
}
}
fn fill<R: Read>(&mut self, reader: &mut R) -> Result<usize, FillError> {
if self.write == self.buffer.len() {
// Shift data
if self.read > 0 {
self.buffer.copy_within(self.read..self.write, 0);
self.write -= self.read;
self.read = 0;
} else {
return Err(FillError::Overflow);
}
}
let n = reader
.read(&mut self.buffer[self.write..])
.map_err(FillError::Io)?;
self.write += n;
Ok(n)
}
pub fn next<'a, R: Read>(&'a mut self, reader: &mut R) -> Result<&'a [u8], FillError> {
loop {
match self.decode() {
Ok(data) => {
return Ok(data);
}
Err(_) => {
self.fill(reader)?;
}
}
}
}
}
Compiler warns me about errors, but I don't understand what's wrong:
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src/lib.rs:47:19
|
45 | pub fn next<'a, R: Read>(&'a mut self, reader: &mut R) -> Result<&'a [u8], FillError> {
| -- lifetime `'a` defined here
46 | loop {
47 | match self.decode() {
| ^^^^^^^^^^^^^ `*self` was mutably borrowed here in the previous iteration of the loop
48 | Ok(data) => {
49 | return Ok(data);
| -------- returning this value requires that `*self` is borrowed for `'a`
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src/lib.rs:52:21
|
45 | pub fn next<'a, R: Read>(&'a mut self, reader: &mut R) -> Result<&'a [u8], FillError> {
| -- lifetime `'a` defined here
46 | loop {
47 | match self.decode() {
| ------------- first mutable borrow occurs here
48 | Ok(data) => {
49 | return Ok(data);
| -------- returning this value requires that `*self` is borrowed for `'a`
...
52 | self.fill(reader)?;
| ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
I guess the first borrowing ended here - Err(_) => {...}
,
but compiler does not.