I have some code like this:

foo.move_right_by(10); //do some stuff foo.move_left_by(10);

It's really important that I perform both of those operations eventually, but I often forget to do the second one after the first. It causes a lot of bugs and I'm wondering if there is an idiomatic Rust way to avoid this problem. Is there a way to get the rust compiler to let me know when I forget?

My idea was to maybe somehow have something like this:

// must_use will prevent us from forgetting this if it is returned by a function #[must_use] pub struct MustGoLeft { steps: usize; } impl MustGoLeft { fn move(&self, foo: &mut Foo) { foo.move_left_by(self.steps); } } // If we don't use left, we'll get a warning about an unused variable let left = foo.move_left_by(10); // Downside: move() can be called multiple times which is still a bug // Downside: left is still available after this call, it would be nice if it could be dropped when move is called left.move();

Is there a better way to accomplish this?

Another idea is to implement Drop and panic! if the struct is dropped without having called that method. This isn't as good though because it's a runtime check and that is highly undesirable.

Edit: I realized my example may have been too simple. The logic involved can get quite complex. For example, we have something like this:

foo.move_right_by(10); foo.open_box(); // like a cardboard box, nothing to do with Box<T> foo.move_left_by(10); // do more stuff... foo.close_box();

Notice how the operations aren't performed in a nice, properly nested order. The only thing that's important is that the inverse operation is always called afterwards. The order sometimes needs to be specified in a certain way in order to make the code work as expected.

We can even have something like this: