use core::fmt::Debug;
use core::marker::PhantomData;
use crate::{MessageContext, MessageResult, Mut, View, ViewMarker, ViewPathTracker};
#[must_use = "View values do nothing unless provided to Xilem."]
pub struct MapState<V, F, ParentState, ChildState, Action, Context> {
map_state: F,
child: V,
phantom: PhantomData<fn(ParentState) -> (ChildState, Action, Context)>,
}
impl<V, F, ParentState, ChildState, Action, Context> Debug
for MapState<V, F, ParentState, ChildState, Action, Context>
where
V: Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("MapAction")
.field("child", &self.child)
.finish_non_exhaustive()
}
}
pub fn map_state<ParentState, ChildState, Action, Context: ViewPathTracker, V, F>(
view: V,
f: F,
) -> MapState<V, F, ParentState, ChildState, Action, Context>
where
ParentState: 'static,
ChildState: 'static,
V: View<ChildState, Action, Context>,
F: Fn(&mut ParentState) -> &mut ChildState + 'static,
{
MapState {
map_state: f,
child: view,
phantom: PhantomData,
}
}
impl<V, F, ParentState, ChildState, Action, Context> ViewMarker
for MapState<V, F, ParentState, ChildState, Action, Context>
{
}
impl<ParentState, ChildState, Action, Context, V, F> View<ParentState, Action, Context>
for MapState<V, F, ParentState, ChildState, Action, Context>
where
ParentState: 'static,
ChildState: 'static,
V: View<ChildState, Action, Context>,
F: Fn(&mut ParentState) -> &mut ChildState + 'static,
Action: 'static,
Context: ViewPathTracker + 'static,
{
type ViewState = V::ViewState;
type Element = V::Element;
fn build(
&self,
ctx: &mut Context,
app_state: &mut ParentState,
) -> (Self::Element, Self::ViewState) {
self.child.build(ctx, (self.map_state)(app_state))
}
fn rebuild(
&self,
prev: &Self,
view_state: &mut Self::ViewState,
ctx: &mut Context,
element: Mut<'_, Self::Element>,
app_state: &mut ParentState,
) {
self.child.rebuild(
&prev.child,
view_state,
ctx,
element,
(self.map_state)(app_state),
);
}
fn teardown(
&self,
view_state: &mut Self::ViewState,
ctx: &mut Context,
element: Mut<'_, Self::Element>,
) {
self.child.teardown(view_state, ctx, element);
}
fn message(
&self,
view_state: &mut Self::ViewState,
message: &mut MessageContext,
element: Mut<'_, Self::Element>,
app_state: &mut ParentState,
) -> MessageResult<Action> {
self.child
.message(view_state, message, element, (self.map_state)(app_state))
}
}