Search code examples
rustborrow-checkermutabilityrust-rustlings

How to debug without changing all the function signatures?


I'm learning Rust by reading the book and doing rustlings and watching videos; I think I understand what's happening here, but I don't understand what to do about it.

#[derive(Debug)]
enum Message {
    ChangeColor(u8, u8, u8),
    Echo(String),
    Move(Point),
    Quit,
}

#[derive(Debug)]
struct Point {
    x: u8,
    y: u8,
}

struct State {
    color: (u8, u8, u8),
    position: Point,
    quit: bool,
    message: String,
}

impl State {
    fn change_color(&mut self, color: (u8, u8, u8)) {
        self.color = color;
    }

    fn quit(&mut self) {
        self.quit = true;
    }

    fn echo(&mut self, s: String) {
        self.message = s
    }

    fn move_position(&mut self, p: Point) {
        self.position = p;
    }

    fn process(&mut self, message: Message) {
        println!("{:#?}", &message);
        match message {
            Message::ChangeColor(r, g, b) => self.change_color((r, g, b)),
            Message::Echo(s) => self.echo(s),
            Message::Move(p) => self.move_position(p),
            Message::Quit => self.quit(),
        }

        println!("{:#?}", &message); // <--------
    }
} 

I understand the value of message is being moved on the last line. I appreciate the memory safety of the borrow checker. But I'm just trying to print message to see what happens to it. I know it's being partially moved and I want to witness what it looks like before and after the move.

Without changing the function signatures of everything, how can i just get a look at it?

And also, is the correct thing to do if I wanted to do something else with message just clone it or set it as mutable somehow?


Solution

  • I want to witness what it looks like before and after the move

    This is not possible in safe Rust, and for good reason. It's like saying "I want to witness what my object looks like before and after destructing it" in C++. After a move (in this case partial, but that's beside the point) the value is no longer usable, and attempts to observe it, which would require unsafe code, would be undefined behavior, i.e. cause crashes or miscompilation.

    If your actual goal is to observe the object after the match e.g. for logging purposes, you can modify your match not to move from the value. The simplest way to do that is to change match message to match &message and modify the match arms accordingly.