react/node/
children.rs

1use std::rc::Rc;
2
3use crate::{AnyNode, ComponentStatic};
4
5/// One or many [`AnyNode`]s whose order will
6/// never change.
7/// When `Children` is used as
8#[derive(Debug, Clone)]
9pub enum Children {
10    Single(Box<AnyNode>),
11    StaticMultiple(Rc<Vec<AnyNode>>),
12}
13
14impl Children {
15    #[inline]
16    pub fn from_static_nodes<T: IntoIterator<Item = AnyNode>>(nodes: T) -> Self {
17        Self::StaticMultiple(Rc::new(Vec::from_iter(nodes)))
18    }
19
20    pub fn from_single(node: AnyNode) -> Children {
21        Self::Single(Box::new(node))
22    }
23
24    /// See [`AnyNode::unsafe_into_js_node_value`] for the safety notes.
25    #[inline]
26    pub(crate) fn unsafe_into_js_array(self) -> js_sys::Array {
27        match self {
28            Children::Single(node) => js_sys::Array::of1(&node.unsafe_into_js_node_value()),
29            Children::StaticMultiple(arr) => match Rc::try_unwrap(arr) {
30                Ok(arr) => js_sys::Array::from_iter(
31                    arr.into_iter().map(AnyNode::unsafe_into_js_node_value),
32                ),
33                Err(arr) => js_sys::Array::from_iter(
34                    arr.iter()
35                        .map(|v| AnyNode::unsafe_into_js_node_value(v.clone())),
36                ),
37            },
38        }
39    }
40}
41
42impl super::Node for Children {
43    #[inline]
44    fn to_node(&self) -> AnyNode {
45        self.clone().into_node()
46    }
47
48    #[inline]
49    fn to_children(&self) -> Option<Children> {
50        Some(self.clone())
51    }
52
53    /// Returns the single node or wrap multiple nodes in a Fragment
54    #[inline]
55    fn into_node(self) -> AnyNode {
56        match self {
57            Children::Single(node) => *node,
58            children => AnyNode::Element(
59                crate::Fragment::create_element(
60                    crate::OptionalChildrenProps {
61                        children: Some(children),
62                    },
63                    None,
64                )
65                .into(),
66            ),
67        }
68    }
69
70    #[inline]
71    fn into_children(self) -> Option<Children> {
72        Some(self)
73    }
74}