Hi everyone!
I am writing a smart-home-like application to control shutters using a Raspberry Pi Zero and a MQTT server. The logic you can see below is designed to stop moving shutters after a certain amount of time.
Code
enum ShutterStatus {
STOPPED,
MOVING(Timer),
}
...
fn action(&mut self, action: ShutterAction) -> Result<(), Error> {
match action {
ShutterAction::STOP => {
self.status = ShutterStatus::STOPPED;
self.up_gpio.switch(&GpioStatus::LOW);
self.down_gpio.switch(&GpioStatus::LOW);
},
ShutterAction::UP => {
self.status =
ShutterStatus::MOVING(Timer::new(20, Box::new(move || self.action(ShutterAction::STOP))));
self.up_gpio.switch(&GpioStatus::HIGH);
self.down_gpio.switch(&GpioStatus::LOW);
},
ShutterAction::DOWN => {
(...)
}
}
Ok(())
}
Problem
However, the code does not compile:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/shutter.rs:44:30
|
44 | Box::new(move || self.action(ShutterAction::STOP)),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 34:5...
--> src/shutter.rs:34:5
|
34 | / fn action(&mut self, action: ShutterAction) -> Result<(), Error> {
35 | | match action {
36 | | ShutterAction::STOP => {
37 | | self.status = ShutterStatus::STOPPED;
... |
52 | | Ok(())
53 | | }
| |_____^
= note: ...so that the types are compatible:
expected &mut shutter::Shutter
found &mut shutter::Shutter
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the expression is assignable:
expected std::boxed::Box<std::ops::Fn() -> std::result::Result<(), error::Error> + std::marker::Send + 'static>
found std::boxed::Box<std::ops::Fn() -> std::result::Result<(), error::Error> + std::marker::Send>
error: aborting due to previous error
For more information about this error, try `rustc --explain E0495`.
error: Could not compile `shutter-control`.
To learn more, run the command again with --verbose.
As far as I unterstand the problem, it cannot be garanteed self.action(...)
still exists after the timer finished, so the compiler forbids this code. I'm running out of ideas how to fix this issue, any idea?
Thanks in advance!