yew_nested_router/
target.rs

1//! Routing target
2
3use std::fmt::Debug;
4use yew::Callback;
5
6/// A target for used by a router.
7pub trait Target: Clone + Debug + Eq + 'static {
8    /// Render only our path segment.
9    fn render_self(&self) -> Vec<String> {
10        let mut path = vec![];
11        self.render_self_into(&mut path);
12        path
13    }
14
15    /// Render the full path, including our children.
16    fn render_path(&self) -> Vec<String> {
17        let mut path = vec![];
18        self.render_path_into(&mut path);
19        path
20    }
21
22    /// Render only our own path component.
23    fn render_self_into(&self, path: &mut Vec<String>);
24
25    /// Render the full path downwards.
26    fn render_path_into(&self, path: &mut Vec<String>);
27
28    /// Parse the target from the provided (segmented) path.
29    ///
30    /// The path will be the local path, with the prefix already removed.
31    fn parse_path(path: &[&str]) -> Option<Self>;
32}
33
34/// Maps a `P`arent target onto a `C`hild target and vice versa.
35#[derive(Debug, PartialEq)]
36pub struct Mapper<P, C> {
37    /// Obtain the child target from the parent
38    pub downwards: Callback<P, Option<C>>,
39    /// Obtain the parent target from the child
40    pub upwards: Callback<C, P>,
41}
42
43impl<P, C> Clone for Mapper<P, C>
44where
45    P: Target,
46    C: Target,
47{
48    fn clone(&self) -> Self {
49        Self {
50            downwards: self.downwards.clone(),
51            upwards: self.upwards.clone(),
52        }
53    }
54}
55
56impl<P, C> Mapper<P, C>
57where
58    P: Target,
59    C: Target,
60{
61    pub fn new<PF, CF>(downwards: PF, upwards: CF) -> Self
62    where
63        PF: Fn(P) -> Option<C> + 'static,
64        CF: Fn(C) -> P + 'static,
65    {
66        Self {
67            downwards: downwards.into(),
68            upwards: upwards.into(),
69        }
70    }
71
72    pub fn new_callback<PF, CF>(downwards: PF, upwards: CF) -> Callback<(), Self>
73    where
74        PF: Fn(P) -> Option<C> + 'static,
75        CF: Fn(C) -> P + 'static,
76    {
77        Self::new(downwards, upwards).into()
78    }
79}
80
81impl<P, C> From<Mapper<P, C>> for Callback<(), Mapper<P, C>>
82where
83    P: Target,
84    C: Target,
85{
86    fn from(mapper: Mapper<P, C>) -> Self {
87        Callback::from(move |()| mapper.clone())
88    }
89}
90
91impl<P, C, PF, CF> From<(PF, CF)> for Mapper<P, C>
92where
93    P: Target,
94    C: Target,
95    PF: Fn(P) -> Option<C> + 'static,
96    CF: Fn(C) -> P + 'static,
97{
98    fn from((down, up): (PF, CF)) -> Self {
99        Self::new(down, up)
100    }
101}