0

I have a buffer which I'm logically dividing into segments. Each segment is built using a SegmentBuilder. I'm trying to temporarily give control of the buffer to the SegmentBuilder until it's finished with its segment, and then create a new SegmentBuilder and so on.

Here's a small example:

struct SegmentBuilder {
    segment: Vec<u32>,
    start: usize,
    end: usize,
}

impl SegmentBuilder {
    fn with_vector_and_offset(vector: Vec<u32>, offset: usize) -> SegmentBuilder {
        SegmentBuilder {
            segment: vector,
            start: offset,
            end: offset,
        }
    }

    fn append(&mut self, integer: u32) -> bool {
        if self.end - self.start > 42 {
            false
        } else {
            self.segment.push(integer);
            self.end = self.end + 1;
            true
        }
    }

    fn seal(self) -> usize {
        self.end
    }
}


struct Buffer {
    storage: Vec<u32>,
    builder: Option<SegmentBuilder>,
}

impl Buffer {
    fn new() -> Buffer {
        Buffer {
            storage: Vec::new(),
            builder: None,
        }
    }

    fn append(&mut self, integer: u32) {
        if let Some(mut builder) = self.builder {
            if !builder.append(integer) {
                let offset = builder.seal();
                self.builder = Some(SegmentBuilder::with_vector_and_offset(self.storage, offset));
            }
        } else {
            self.builder = Some(SegmentBuilder::with_vector_and_offset(self.storage, 0));
            self.append(integer);
        }
    }
}

This gives a compile error:

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:46:36
   |
46 |         if let Some(mut builder) = self.builder {
   |                     -----------    ^^^^ cannot move out of borrowed content
   |                     |
   |                     hint: to prevent move, use `ref builder` or `ref mut builder`

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:49:76
   |
49 |                 self.builder = Some(SegmentBuilder::with_vector_and_offset(self.storage, offset));
   |                                                                            ^^^^ cannot move out of borrowed content

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:52:72
   |
52 |             self.builder = Some(SegmentBuilder::with_vector_and_offset(self.storage, 0));
   |                                                                        ^^^^ cannot move out of borrowed content

Is this pattern possible in Rust? If so, what should I do to fix the error?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Shmoopy
  • 5,334
  • 4
  • 36
  • 72
  • *another member in the same struct* — which two member variables inside the same struct are you referring to? – Shepmaster Jun 19 '17 at 18:47
  • @Shepmaster I'm trying to temporarily move Buffer::storage to Buffer::builder::segment – Shmoopy Jun 19 '17 at 18:50
  • 1
    You cannot leave a member field in an undefined state; that could lead to accessing memory when you shouldn't, which Rust is designed to prevent. You will need to swap in a fresh `Vec` to replace the previous one. You could also just pass in a mutable reference to the `Vec` instead of the entire owned `Vec`. – Shepmaster Jun 19 '17 at 18:54

0 Answers0