my struct
use web_sys::{Document, Element, window};
use wasm_bindgen::{UnwrapThrowExt, JsCast};
use std::cell::RefCell;
use wasm_bindgen::closure::Closure;
use web_sys::console::log_1;
pub struct Draggable2 {
doc: Document,
pub(crate) body: Element,
prev: Option<Element>,
pub(crate) curr: Option<Element>,
dragged: Option<Element>,
}
impl Draggable2 {
pub(crate) fn new() {
let doc = window().unwrap_throw().document().unwrap_throw();
let body = doc.query_selector("body").unwrap_throw().unwrap_throw();
let _self = &mut Draggable2 { doc, body, prev: None, curr: None, dragged: None };
_self.drag_handler();
}
}
problem accor when I use self.curr inside the clouse with move
use web_sys::console::log_1;
use crate::editor::plugins::draggable_2::draggable_2::Draggable2;
use wasm_bindgen::prelude::Closure;
use wasm_bindgen::JsCast;
impl<'a> Draggable2 {
pub fn drag_handler(&'a mut self) {
let closure = Closure::wrap(Box::new(move |event: web_sys::DragEvent| {
log_1(&format!("{:#?}", self.curr).into());
self.curr = get_element(event.psge_x(),event.page_y())
}) as Box<dyn FnMut(_)>);
self.body.add_event_listener_with_callback("drop", &closure.as_ref().unchecked_ref());
closure.forget();
}
}
full error message.
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/editor/plugins/draggable_2/drag_handler.rs:13:46
|
13 | let closure = Closure::wrap(Box::new(move |event: web_sys::DragEvent| {
| ______________________________________________^
14 | | log_1(&format!("{:#?}", self.curr).into());
15 | | }) as Box<dyn FnMut(_)>);
| |_________^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
--> src/editor/plugins/draggable_2/drag_handler.rs:7:6
|
7 | impl<'a> Draggable2 {
| ^^
note: ...so that the types are compatible
--> src/editor/plugins/draggable_2/drag_handler.rs:13:46
|
13 | let closure = Closure::wrap(Box::new(move |event: web_sys::DragEvent| {
| ______________________________________________^
14 | | log_1(&format!("{:#?}", self.curr).into());
15 | | }) as Box<dyn FnMut(_)>);
| |_________^
= note: expected `(&mut Draggable2,)`
found `(&'a mut Draggable2,)`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the types are compatible
--> src/editor/plugins/draggable_2/drag_handler.rs:13:23
|
13 | let closure = Closure::wrap(Box::new(move |event: web_sys::DragEvent| {
| ^^^^^^^^^^^^^
= note: expected `<dyn FnMut(DragEvent) as WasmClosure>`
found `<(dyn FnMut(DragEvent) + 'static) as WasmClosure>`
Because
self
is a reference,self.curr
will not get moved into the closure, despite themove
annotation before it. So the closure has to capture a reference, i.e.&self.curr
. The lifetime of this reference is'a
, so the closure also inherits that lifetime. ButClosure::wrap
expects a closure with a lifetime of'static
, so valid "forever".Your question doesn't contain enough information on how to solve this. It might be that moving a clone into the closure is sufficient
or you have to somehow share the current value with the closure, for example by changing the type of
self.curr
to a shareableRc<RefCell<Option<Element>>
.