react/node/
any.rs

1use std::rc::Rc;
2
3use wasm_bindgen::JsValue;
4
5use super::{AnyNodeValue, Node};
6
7#[derive(Debug, Clone)]
8pub enum AnyNode {
9    /// No node.
10    /// Will be converted to `null` when passed to js
11    Null,
12    /// Valid `ReactNode` excluding elements.
13    /// Such as number, string, boolean.
14    Value(AnyNodeValue),
15    /// Element
16    Element(crate::Element),
17    /// Array of keyed elements
18    Multiple(Rc<Vec<crate::Keyed<crate::Element>>>),
19}
20
21impl AnyNode {
22    #[inline]
23    pub fn null() -> Self {
24        Self::Null
25    }
26
27    /// Consumes `AnyNode` and output the node value
28    /// so that it can be passed to js.
29    ///
30    /// Note that the produced JsValue shouldn't
31    /// be cloned due to the following reasons:
32    ///
33    /// If it is an element
34    /// it will drop the `use_render` closure
35    /// which has been previously forgotten in
36    /// [`crate::BridgeElementData::unsafe_create_element_js`].
37    #[inline]
38    pub(crate) fn unsafe_into_js_node_value(self) -> JsValue {
39        let js = match self {
40            AnyNode::Null => JsValue::NULL,
41            AnyNode::Value(v) => v.into(),
42            AnyNode::Element(el) => el.unsafe_into_js_element().into(),
43            AnyNode::Multiple(els) => (match Rc::try_unwrap(els) {
44                Ok(els) => js_sys::Array::from_iter(
45                    els.into_iter()
46                        .map(|node| node.0.into_node().unsafe_into_js_node_value()),
47                ),
48                Err(els) => js_sys::Array::from_iter(
49                    els.iter()
50                        .map(|node| node.0.to_node().unsafe_into_js_node_value()),
51                ),
52            })
53            .into(),
54        };
55        js
56    }
57}
58
59impl Node for AnyNode {
60    #[inline]
61    fn to_node(&self) -> AnyNode {
62        self.clone()
63    }
64
65    #[inline]
66    fn to_children(&self) -> Option<crate::Children> {
67        Some(crate::Children::from_single(self.clone()))
68    }
69
70    #[inline]
71    fn into_node(self) -> AnyNode {
72        self
73    }
74
75    #[inline]
76    fn into_children(self) -> Option<crate::Children>
77    where
78        Self: Sized,
79    {
80        Some(crate::Children::from_single(self))
81    }
82}