1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use std::any::Any;
use std::rc::Rc;

use crate::VBody;

pub trait RenderComponent: 'static {
    fn render(&self, props: &dyn Any) -> VBody;
}

#[derive(Clone)]
pub struct Component(Rc<ComponentInner>);

impl Component {
    pub fn new(func: impl RenderComponent, props: Box<dyn Any>) -> Self {
        Self(Rc::new(ComponentInner::new(func, props)))
    }

    pub fn render(&self) -> String {
        self.0.render()
    }
}

struct ComponentInner {
    func: Box<dyn RenderComponent>,
    props: Box<dyn Any>,
}

impl ComponentInner {
    fn new(func: impl RenderComponent, props: Box<dyn Any>) -> Self {
        Self {
            func: Box::new(func),
            props,
        }
    }

    fn render(&self) -> String {
        self.func.render(self.props.as_ref()).render()
    }
}

impl<F> RenderComponent for F
where
    F: Fn(&dyn Any) -> VBody + 'static,
{
    fn render(&self, props: &dyn Any) -> VBody {
        self(props)
    }
}