use std::marker::PhantomData;
use crate::{
Context,
ui::{Event, Lens, View, event::EventResult},
};
pub struct Adapt<Outer, Inner, OuterMsg, L, M, V>
where
L: Lens<Outer, Inner>,
V: View<Inner>,
M: Fn(V::Message) -> OuterMsg,
{
lens: L,
mapper: M,
view: V,
_marker: PhantomData<(Outer, Inner, OuterMsg)>,
}
pub fn adapt<Outer, Inner, OuterMsg, L, M, V>(
view: V,
lens: L,
mapper: M,
) -> Adapt<Outer, Inner, OuterMsg, L, M, V>
where
L: Lens<Outer, Inner>,
V: View<Inner>,
M: Fn(V::Message) -> OuterMsg,
{
Adapt {
lens,
mapper,
view,
_marker: PhantomData,
}
}
impl<Outer, Inner, OuterMsg, L, M, V> View<Outer> for Adapt<Outer, Inner, OuterMsg, L, M, V>
where
L: Lens<Outer, Inner>,
V: View<Inner>,
M: Fn(V::Message) -> OuterMsg,
{
type Element = V::Element;
type Message = OuterMsg;
fn build(&self, ctx: &mut Context) -> Self::Element {
self.view.build(ctx)
}
fn rebuild(&self, prev: &Self, ctx: &mut Context, element: &mut Self::Element) {
self.view.rebuild(&prev.view, ctx, element)
}
fn rebuild_with_parent(
&self,
prev: &Self,
ctx: &mut Context,
element: &mut Self::Element,
parent: crate::Node,
next_sibling: Option<crate::Node>,
) {
self.view
.rebuild_with_parent(&prev.view, ctx, element, parent, next_sibling)
}
fn teardown(&self, ctx: &mut Context, element: &mut Self::Element) {
self.view.teardown(ctx, element)
}
fn get_node(&self, element: &Self::Element) -> crate::Node {
self.view.get_node(element)
}
fn handle_event(
&self,
element: &mut Self::Element,
state: &Outer,
event: Event,
ctx: &mut Context,
) -> (EventResult, Option<Self::Message>) {
let inner_state = self.lens.get(state);
let (result, inner_msg) = self.view.handle_event(element, inner_state, event, ctx);
let outer_msg = inner_msg.map(&self.mapper);
(result, outer_msg)
}
}
pub trait ViewAdaptExt<Inner>: View<Inner> + Sized {
fn adapt<Outer, OuterMsg, L, M>(
self,
lens: L,
mapper: M,
) -> Adapt<Outer, Inner, OuterMsg, L, M, Self>
where
L: Lens<Outer, Inner>,
M: Fn(Self::Message) -> OuterMsg,
{
adapt(self, lens, mapper)
}
}
impl<Inner, V: View<Inner>> ViewAdaptExt<Inner> for V {}