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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use std::{
    cmp::PartialEq,
    fmt,
    rc::Rc,
};

use crate::{
    computed::{Computed, Value},
    virtualdom::models::{
        vdom_component_id::VDomComponentId,
        vdom_element::VDomElement
    }
};

/// A component is a virtual dom element with render function attached to it.
///
/// Usually used as a main component for the application.
///
/// ```rust,no_run
/// use vertigo::{Computed, Dependencies, dev::VDomComponent, VDomElement, html};
///
/// // Here some driver should be used instead of pure dependency graph.
/// let deps = Dependencies::default();
///
/// let state = deps.new_computed_from(5);
///
/// fn comp_render(state: &Computed<i32>) -> VDomElement {
///     html! { <p>{*state.get_value()}</p> }
/// }
///
/// let main_component = VDomComponent::new(state, comp_render);
/// ```
#[derive(Clone)]
pub struct VDomComponent {
    pub id: VDomComponentId,
    pub view: Computed<VDomElement>,
}

impl VDomComponent {
    pub fn new<T: PartialEq + 'static>(params: Computed<T>, render: fn(&Computed<T>) -> VDomElement) -> VDomComponent {
        let component_id = VDomComponentId::new(&params, render);
        let view = params.map_for_render(render);

        VDomComponent { id: component_id, view }
    }

    pub fn from_value<T: PartialEq + 'static>(params: Value<T>, render: fn(&Value<T>) -> VDomElement) -> VDomComponent {
        let component_id = VDomComponentId::new_value(&params, render);

        let deps = params.deps();

        let comp = deps.new_computed_from(params);

        let view = comp.map(move |wrapper_computed: &Computed<Value<T>>| -> VDomElement {
            let value: Rc<Value<T>> = wrapper_computed.get_value();
            let value: &Value<T> = value.as_ref();
            render(value)
        });

        VDomComponent { id: component_id, view }
    }
}

impl fmt::Debug for VDomComponent {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("VDomElement")
            .field("id", &self.id)
            .field("view", &self.view.get_value())
            .finish()
    }
}