alchemy_lifecycle/rsx/
virtual_node.rs

1//! Implements the `RSX::VirtualNode` struct, which is a bit of a recursive
2//! structure.
3
4use std::any::Any;
5use std::fmt::{Display, Debug};
6
7use alchemy_styles::StylesList;
8
9use crate::reconciler::key::ComponentKey;
10use crate::rsx::RSX;
11use crate::traits::Component;
12
13/// A VirtualNode is akin to an `Element` in React terms. Here, we provide a way
14/// for lazy `Component` instantiation, properties, children and so on.
15pub struct VirtualNode {
16    /// Used in debugging/printing/etc.
17    pub tag: &'static str,
18
19    /// Used for determining which CSS styles should be applied to this node.
20    /// This property is accessed often enough that it's separated out here.
21    pub styles: StylesList,
22
23    /// `Component` instances are created on-demand, if the reconciler deems it be so. This
24    /// is a closure that should return an instance of the correct type.
25    pub create_component_fn: fn(key: ComponentKey) -> Box<Component>,
26
27    /// When some RSX is returned, we scoop up the props inside a special block, and then shove
28    /// them in here as an `Any` object. When you `derive(Props)` on a `Component` struct, it 
29    /// creates a setter that specifically handles downcasting and persisting props for you.
30    pub props: Box<Any>,
31
32    /// Child components for this node.
33    pub children: Vec<RSX>
34}
35
36impl Display for VirtualNode {
37    /// Special formatting for displaying nodes.
38    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
39        write!(f, "<{}>", self.tag)?;
40
41        for child in &self.children {
42            write!(f, "{:?}", child)?;
43        }
44
45        write!(f, "</{}>", self.tag)
46    }
47}
48
49impl Debug for VirtualNode {
50    /// Special formatting for debugging nodes.
51    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
52        write!(f, "VirtualNode({})", self.tag)
53    }
54}