diff options
-rw-r--r-- | native/src/widget/action.rs | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/native/src/widget/action.rs b/native/src/widget/action.rs index c78c5776..9aa79dec 100644 --- a/native/src/widget/action.rs +++ b/native/src/widget/action.rs @@ -3,6 +3,8 @@ use crate::widget::Id; use iced_futures::MaybeSend; +use std::rc::Rc; + /// An operation to be performed on the widget tree. #[allow(missing_debug_implementations)] pub struct Action<T>(Box<dyn Operation<T>>); @@ -24,7 +26,7 @@ impl<T> Action<T> { { Action(Box::new(Map { operation: self.0, - f: Box::new(f), + f: Rc::new(f), })) } @@ -37,7 +39,7 @@ impl<T> Action<T> { #[allow(missing_debug_implementations)] struct Map<A, B> { operation: Box<dyn Operation<A>>, - f: Box<dyn Fn(A) -> B>, + f: Rc<dyn Fn(A) -> B>, } impl<A, B> Operation<B> for Map<A, B> @@ -50,38 +52,44 @@ where id: Option<&Id>, operate_on_children: &mut dyn FnMut(&mut dyn Operation<B>), ) { - struct MapRef<'a, A, B> { + struct MapRef<'a, A> { operation: &'a mut dyn Operation<A>, - f: &'a dyn Fn(A) -> B, } - impl<'a, A, B> Operation<B> for MapRef<'a, A, B> { + impl<'a, A, B> Operation<B> for MapRef<'a, A> { fn container( &mut self, id: Option<&Id>, operate_on_children: &mut dyn FnMut(&mut dyn Operation<B>), ) { - let Self { operation, f } = self; + let Self { operation, .. } = self; operation.container(id, &mut |operation| { - operate_on_children(&mut MapRef { operation, f }); + operate_on_children(&mut MapRef { operation }); }); } - fn scrollable(&mut self, state: &mut dyn Scrollable, id: Option<&Id>) { + fn scrollable( + &mut self, + state: &mut dyn Scrollable, + id: Option<&Id>, + ) { self.operation.scrollable(state, id); } - fn focusable(&mut self, state: &mut dyn Focusable, id: Option<&Id>) { + fn focusable( + &mut self, + state: &mut dyn Focusable, + id: Option<&Id>, + ) { self.operation.focusable(state, id); } } - let Self { operation, f } = self; + let Self { operation, .. } = self; MapRef { operation: operation.as_mut(), - f, } .container(id, operate_on_children); } @@ -109,4 +117,19 @@ where ) { self.operation.text_input(state, id); } + + fn finish(&self) -> operation::Outcome<B> { + match self.operation.finish() { + operation::Outcome::None => operation::Outcome::None, + operation::Outcome::Some(output) => { + operation::Outcome::Some((self.f)(output)) + } + operation::Outcome::Chain(next) => { + operation::Outcome::Chain(Box::new(Map { + operation: next, + f: self.f.clone(), + })) + } + } + } } |