1use core::fmt::Debug;
5use core::marker::PhantomData;
6
7use crate::{MessageContext, MessageResult, Mut, View, ViewMarker, ViewPathTracker};
8
9#[must_use = "View values do nothing unless provided to Xilem."]
13pub struct MapMessage<
14 V,
15 State,
16 ParentAction,
17 ChildAction,
18 Context,
19 F = fn(&mut State, ChildAction) -> ParentAction,
21> {
22 map_fn: F,
23 child: V,
24 phantom: PhantomData<fn() -> (State, ParentAction, ChildAction, Context)>,
25}
26
27impl<V, State, ParentAction, ChildAction, Context, F> Debug
28 for MapMessage<V, State, ParentAction, ChildAction, Context, F>
29where
30 V: Debug,
31{
32 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33 f.debug_struct("MapAction")
34 .field("child", &self.child)
35 .finish_non_exhaustive()
36 }
37}
38
39pub fn map_action<State, ParentAction, ChildAction, Context: ViewPathTracker, V, F>(
69 view: V,
70 map_fn: F,
71) -> MapMessage<
72 V,
73 State,
74 ParentAction,
75 ChildAction,
76 Context,
77 impl Fn(&mut State, MessageResult<ChildAction>) -> MessageResult<ParentAction> + 'static,
78>
79where
80 State: 'static,
81 ParentAction: 'static,
82 ChildAction: 'static,
83 V: View<State, ChildAction, Context>,
84 F: Fn(&mut State, ChildAction) -> ParentAction + 'static,
85{
86 MapMessage {
87 map_fn: move |app_state: &mut State, result: MessageResult<ChildAction>| {
88 result.map(|action| map_fn(app_state, action))
89 },
90 child: view,
91 phantom: PhantomData,
92 }
93}
94
95pub fn map_message<State, ParentAction, ChildAction, Context: ViewPathTracker, V, F>(
100 view: V,
101 map_fn: F,
102) -> MapMessage<V, State, ParentAction, ChildAction, Context, F>
103where
104 State: 'static,
105 ParentAction: 'static,
106 ChildAction: 'static,
107 V: View<State, ChildAction, Context>,
108 F: Fn(&mut State, MessageResult<ChildAction>) -> MessageResult<ParentAction> + 'static,
109{
110 MapMessage {
111 map_fn,
112 child: view,
113 phantom: PhantomData,
114 }
115}
116
117impl<V, State, ParentAction, ChildAction, F, Context> ViewMarker
118 for MapMessage<V, State, ParentAction, ChildAction, Context, F>
119{
120}
121impl<V, State, ParentAction, ChildAction, Context, F> View<State, ParentAction, Context>
122 for MapMessage<V, State, ParentAction, ChildAction, Context, F>
123where
124 V: View<State, ChildAction, Context>,
125 State: 'static,
126 ParentAction: 'static,
127 ChildAction: 'static,
128 F: Fn(&mut State, MessageResult<ChildAction>) -> MessageResult<ParentAction> + 'static,
129 Context: ViewPathTracker + 'static,
130{
131 type ViewState = V::ViewState;
132 type Element = V::Element;
133
134 fn build(&self, ctx: &mut Context, app_state: &mut State) -> (Self::Element, Self::ViewState) {
135 self.child.build(ctx, app_state)
136 }
137
138 fn rebuild(
139 &self,
140 prev: &Self,
141 view_state: &mut Self::ViewState,
142 ctx: &mut Context,
143 element: Mut<'_, Self::Element>,
144 app_state: &mut State,
145 ) {
146 self.child
147 .rebuild(&prev.child, view_state, ctx, element, app_state);
148 }
149
150 fn teardown(
151 &self,
152 view_state: &mut Self::ViewState,
153 ctx: &mut Context,
154 element: Mut<'_, Self::Element>,
155 ) {
156 self.child.teardown(view_state, ctx, element);
157 }
158
159 fn message(
160 &self,
161 view_state: &mut Self::ViewState,
162 message: &mut MessageContext,
163 element: Mut<'_, Self::Element>,
164 app_state: &mut State,
165 ) -> MessageResult<ParentAction> {
166 let child_result = self.child.message(view_state, message, element, app_state);
167 (self.map_fn)(app_state, child_result)
168 }
169}