0
votes

I'm having trouble with this code. I have no idea why it errors. It's supposed to take camera input and then put that inside of a buffer struct, contained inside the putter struct.

extern crate rscam;
// use std::fs::File;
// use std::io::prelude::*;

const WIDTH: usize = 1280;
const HEIGHT: usize = 720;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Pyxel {
    r: u8,
    g: u8,
    b: u8,
}

impl Pyxel {
    fn new() -> Pyxel {
        Pyxel { r: 0, g: 0, b: 0 }
    }
}

#[repr(transparent)]
struct Buffer {
    pyxels: [[Pyxel; WIDTH]; HEIGHT],
}

// impl Buffer {
//  fn new(s: [[Pyxel; WIDTH]; HEIGHT]) -> Buffer {
//      Buffer {
//          pyxels: s,
//      }
//  }
// }

struct Putter {
    x: usize,
    y: usize,
    buffer: &'static mut Buffer,
}

impl Putter {
    fn put_pyxel(&mut self, r: u8, g: u8, b: u8) {
        if self.x >= WIDTH {
            self.move_down();
        }
        let col = self.x;
        let row = self.y;
        self.buffer.pyxels[row][col] = Pyxel { r: r, g: g, b: b };
        self.x += 1;
    }
    fn move_down(&mut self) {
        self.y += 1;
    }
    fn new() -> Putter {
        Putter {
            x: 0,
            y: 0,
            buffer: &mut Buffer {
                pyxels: [[Pyxel::new(); WIDTH]; HEIGHT],
            },
        }
    }
}

fn main() {
    let mut camera = rscam::new("/dev/video0").unwrap();
    camera
        .start(&rscam::Config {
            interval: (1, 30),
            resolution: (1280, 720),
            format: b"RGB3",
            ..Default::default()
        })
        .unwrap();

    let frame = camera.capture().unwrap();

    let mut putter = Putter::new();
}

It errors:

error[E0597]: borrowed value does not live long enough
   --> src/main.rs:65:20
   |
57 |               buffer: &mut Buffer {
   |  __________________________^
58 | |                 pyxels: [[Pyxel::new(); WIDTH]; HEIGHT],
59 | |             },
   | |_____________^ temporary value does not live long enough
60 |           }
61 |       }
   |       - temporary value only lives until here
   |
  = note: borrowed value must be valid for the static lifetime..

How do I use the buffer inside of the putter (structs)?

For the most part, I understand what this errors means, not how it works. I just need a workaround or a solution. Any help is appreciated. I could have written this better but im tired.

1
The error itself notifies you about the problem, Since you are creating Buffer in the scope and assigning it's pointer to your struct but this value does not live enough because it has already destroyed since the value is not stored in anywhere.Akiner Alkan
Why is Putter::buffer a reference? Why not put the buffer directly in the Putter?Jmb
What is the difference exactly?Jared Landers

1 Answers

2
votes

This is more or less logical error for me. You should carefully read about Rust ownership.

Consider thinking about how would your code work.

struct Putter {
    x: usize,
    y: usize,
    buffer: &'static mut Buffer,
}

Buffer is a reference which you have lifetime equal to the lifetime of the program, 'static tells compiler that. Error message is pretty clear, you're creating temporary value in place and borrowing it. It will be destroyed right after exiting scope, so your reference will be pointing to invalid memory. Dangling references are prohibited in Rust. In language like C++ this example will compile fine, but will result in run-time error.

To fix this issue buffer should own value and struct design should be rethought while keeping attention to lifetimes.

struct Putter {
    x: usize,
    y: usize,
    buffer: Buffer,
}