Wazzup crabbers. So I have stumbled upon this real doozy of a problem that I would appreciate a helping hand with. For context, I am working on React-style state hooks for dumle, the virtual DOM library. What I have working is this
let node = UseState::new(|state: &i32, set_state| {
html! {
<div>
{ state.to_string() }
<button click=move |_| set_state(&|state: &mut i32| *state += 1),>
{"Increment"}
</button>
</div>
}
});
You specify a state, in this case i32
, and a render function which returns a virtual node given the current state. This gets stored in a struct (see src/hook.rs:12) behind some Rc and RefCell:s:
struct UseStateData<N, S, R> {
/// The virtual node.
vnode: N,
/// The mounted DOM node.
node: Node,
/// User data.
user: S,
/// The render function.
render: R,
}
What I now want is to allow the rendered virtual nodes to keep references to the state, for example:
fn render() -> impl Vnode {
let node = UseState::new(|state: &String, set_state| Text(state));
node
}
but that gives the error:
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src/lib.rs:44:52
|
44 | UseState::new(|state: &String, set_state| Text(&state))
| ^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 44:19...
--> src/lib.rs:44:19
|
44 | UseState::new(|state: &String, set_state| Text(&state))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that the type `&std::string::String` is not borrowed for too long
--> src/lib.rs:44:52
|
44 | UseState::new(|state: &String, set_state| Text(&state))
| ^^^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that return value is valid for the call
--> src/lib.rs:42:28
|
42 | fn render() -> impl Vnode {
| ^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0495`.
Here the trait bounds are (see src/hook.rs:95):
S: Default + 'static // The state
R: FnMut(&S, Box<dyn Fn(&Fn(&mut S))>) -> N + 'static // The render function
N: Vnode + 'static // The virtual node
Am I right in thinking that you would have to pin everything since UseStateData
would be a self-referential struct? If so how would the trait bound for R
look and how would you accommodate the lifetime? Don't really know where to begin - just removing the 'static
on N
doesn't get me much further.
I'll see if I can come up with a MVE.
Thanks in advance for any help on this.