I want to move a value into a mutable closure. FnOnce is very close to what I need, but I also want to mutate some values just outside the closure as well. Is it possible to make a FnMutOnce?, If not, I'll just re-arrange some code.
I have a with_frp_context
with one type signature in observe:
fn observe<F,F2>(&self, env: &mut ENV, with_frp_context: &F, observer: F2) -> Box<Fn(&mut Self)>
where
F:Fn(&mut ENV,&FnOnce(&mut FrpContext<ENV>)),
F2:Fn(&mut ENV,&A) + 'static {
let observer_id = self.free_observer_id;
with_frp_context(
env,
&move |frp_context| {
if let Some(cell) = frp_context.cell_map.get_mut(&observer_id) {
cell.free_observer_id = cell.free_observer_id + 1;
cell.observer_map.insert(observer_id, Box::new(
move |env, value| {
match value.as_ref().downcast_ref::<A>() {
Some(value) => observer(env, value),
None => ()
}
}
));
}
}
);
Box::new(move |cell| {
cell.observer_map.remove(&observer_id);
})
}
Then a different type signature in another method:
pub fn transaction<F,F2>(env: &mut ENV, with_frp_context: &F, k: &mut F2)
where F:Fn(&mut ENV, &FnMut(&mut FrpContext<ENV>)), F2: FnMut(&mut ENV, &F)
{
with_frp_context(
env,
&|frp_context| {
frp_context.transaction_depth = frp_context.transaction_depth + 1;
}
);
k(env, with_frp_context);
let mut final_transaction_depth = 0;
with_frp_context(
env,
&mut |frp_context| {
frp_context.transaction_depth = frp_context.transaction_depth - 1;
final_transaction_depth = frp_context.transaction_depth;
}
);
if final_transaction_depth == 0 {
FrpContext::propergate(env, with_frp_context);
}
}
However I'd like to use the same type signature for with_frp_context
in all methods for consistency and ease of use.
I might be able to just make another trait like:
pub trait WithFrpContext<ENV> {
fn call<S>(env: &mut ENV, state: &mut S, k: &FnOnce(&mut FrpContext<ENV>, &mut S));
}
But would be a little in-convenient to the end-user as they can not use closure syntax.