I have a Reader instance with a method that consumes the Reader and returns a Writer and the Writer can similarly get back to a Reader again. It's trivial to use immutably, but I can't figure out how to hide the immutability from callers and just do the reader-writer-reader dance behind the scenes with a mutable Self.
Essentially I'd like something like:
struct Container<'a> {
reader: Reader<'a, File>
}
fn update(&mut self) {
let writer = self.reader.as_writer();
writer.write_something();
self.reader = writer.as_reader();
}
which just gives cannot move out of borrowed content
error. Tried to add a Box, Cell, or RefCell around the Reader which just lead to other errors.
Can the reader
be hidden behind a mutable interface or does it force the whole struct hierarchy to be mutable as well? (i.e. similar to IO in Haskell)
Self contained sample with the types matching the real thing (I think)
#[derive(Debug)]
struct NoCopy(u32);
#[derive(Debug)]
struct Flipper<'a, T: 'a> {
data: &'a mut T,
}
#[derive(Debug)]
struct Flopper<'a, T: 'a> {
data: &'a mut T,
}
impl<'a, T> Flipper<'a, T> {
fn flip(self) -> Flopper<'a, T> {
Flopper{data: self.data}
}
}
impl<'a, T> Flopper<'a, T> {
fn flop(self) -> Flipper<'a, T> {
Flipper{data: self.data}
}
}
#[derive(Debug)]
struct Container<'a, T: 'a> {
flipper: Flipper<'a, T>,
}
impl<'a, T> Container<'a, T> {
fn run(&mut self) {
self.flipper = self.flipper.flip().flop();
}
}
fn main() {
let f = Flipper{data: &mut NoCopy(42)};
let f = f.flip().flop();
println!("f={:?}", f);
let mut c = Container{flipper: f};
c.run();
println!("c={:?}", c);
}
error[E0507]: cannot move out of borrowed content --> src/main.rs:29:24 | 29 | self.flipper = self.flipper.flip().flop(); | ^^^^ cannot move out of borrowed content