use std::fmt::Debug;
use yew::Callback;
pub trait Target: Clone + Debug + Eq + 'static {
fn render_self(&self) -> Vec<String> {
let mut path = vec![];
self.render_self_into(&mut path);
path
}
fn render_path(&self) -> Vec<String> {
let mut path = vec![];
self.render_path_into(&mut path);
path
}
fn render_self_into(&self, path: &mut Vec<String>);
fn render_path_into(&self, path: &mut Vec<String>);
fn parse_path(path: &[&str]) -> Option<Self>;
}
#[derive(Debug, PartialEq)]
pub struct Mapper<P, C> {
pub downwards: Callback<P, Option<C>>,
pub upwards: Callback<C, P>,
}
impl<P, C> Clone for Mapper<P, C>
where
P: Target,
C: Target,
{
fn clone(&self) -> Self {
Self {
downwards: self.downwards.clone(),
upwards: self.upwards.clone(),
}
}
}
impl<P, C> Mapper<P, C>
where
P: Target,
C: Target,
{
pub fn new<PF, CF>(downwards: PF, upwards: CF) -> Self
where
PF: Fn(P) -> Option<C> + 'static,
CF: Fn(C) -> P + 'static,
{
Self {
downwards: downwards.into(),
upwards: upwards.into(),
}
}
pub fn new_callback<PF, CF>(downwards: PF, upwards: CF) -> Callback<(), Self>
where
PF: Fn(P) -> Option<C> + 'static,
CF: Fn(C) -> P + 'static,
{
Self::new(downwards, upwards).into()
}
}
impl<P, C> From<Mapper<P, C>> for Callback<(), Mapper<P, C>>
where
P: Target,
C: Target,
{
fn from(mapper: Mapper<P, C>) -> Self {
Callback::from(move |()| mapper.clone())
}
}
impl<P, C, PF, CF> From<(PF, CF)> for Mapper<P, C>
where
P: Target,
C: Target,
PF: Fn(P) -> Option<C> + 'static,
CF: Fn(C) -> P + 'static,
{
fn from((down, up): (PF, CF)) -> Self {
Self::new(down, up)
}
}