I'm trying to write a wrapper for a slice that allows bounds checking and actual writing to the slice be distanced from each other so that other processing can happen in between.
The way am trying to accomplish this is to have the bounds checking method on the wrapper return a handle that mutably borrows the wrapper itself so that no other calls on the wrapper can be made as long as the handle is alive. Then, I'm trying to make the method on the handle that actually does the writing consume the handle itself in order to make the handle no longer be alive after the writing. At this point, I'd expect to be able to obtain a new handle from the wrapper, since the wrapper is no longer mutably borrowed.
The code below compiles. However, when I uncomment the loop, the compiler complains that I can't borrow the wrapper again, because the previous borrow ends at the end of the function.
Clearly, I misunderstanding some basics.
Why doesn't the borrow end at the end of the loop body so that the next iteration could do a new borrow? Is there some existing code that I should look at that implements the kind of pattern that I'm trying to implement per the description above?
struct Handle<'a> {
dest: &'a Destination<'a>,
}
impl<'a> Handle<'a> {
fn new(dst: &'a mut Destination<'a>) -> Handle<'a> {
Handle { dest: dst }
}
fn write(mut self, bmp: u16) {
// Eventually write something unsafe here that writes via dest to its
// wrapped slice without bounds checking and increment pos.
}
}
struct Destination<'a> {
slice: &'a [u16],
pos: usize,
}
impl<'a> Destination<'a> {
fn new(dst: &mut [u16]) -> Destination {
Destination { slice: dst, pos: 0 }
}
fn check_space(&'a mut self) -> Option<Handle<'a>> {
if self.pos < self.slice.len() {
Some(Handle::new(self))
} else {
None
}
}
}
fn main() {
let mut v = vec![1u16, 2u16, 3u16];
let mut d = Destination::new(&mut v[..]);
//loop {
match d.check_space() {
None => {
println!("No space");
return;
},
Some(h) => {
// do something else here
h.write(0u16)
},
}
//}
println!("End");
}