raui_core/widget/
node.rs

1use crate::{
2    Prefab,
3    props::Props,
4    widget::{
5        component::{WidgetComponent, WidgetComponentPrefab},
6        unit::{WidgetUnitNode, WidgetUnitNodePrefab},
7    },
8};
9use serde::{Deserialize, Serialize};
10
11#[allow(clippy::large_enum_variant)]
12#[derive(Debug, Default, Clone)]
13pub enum WidgetNode {
14    #[default]
15    None,
16    Component(WidgetComponent),
17    Unit(WidgetUnitNode),
18    Tuple(Vec<WidgetNode>),
19}
20
21impl WidgetNode {
22    pub fn is_none(&self) -> bool {
23        match self {
24            Self::None => true,
25            Self::Unit(unit) => unit.is_none(),
26            Self::Tuple(v) => v.is_empty(),
27            _ => false,
28        }
29    }
30
31    pub fn is_some(&self) -> bool {
32        match self {
33            Self::None => false,
34            Self::Unit(unit) => unit.is_some(),
35            Self::Tuple(v) => !v.is_empty(),
36            _ => true,
37        }
38    }
39
40    pub fn as_component(&self) -> Option<&WidgetComponent> {
41        match self {
42            Self::Component(c) => Some(c),
43            _ => None,
44        }
45    }
46
47    pub fn as_unit(&self) -> Option<&WidgetUnitNode> {
48        match self {
49            Self::Unit(u) => Some(u),
50            _ => None,
51        }
52    }
53
54    pub fn as_tuple(&self) -> Option<&[WidgetNode]> {
55        match self {
56            Self::Tuple(v) => Some(v),
57            _ => None,
58        }
59    }
60
61    pub fn props(&self) -> Option<&Props> {
62        match self {
63            Self::Component(c) => Some(&c.props),
64            Self::Unit(u) => u.props(),
65            _ => None,
66        }
67    }
68
69    pub fn props_mut(&mut self) -> Option<&mut Props> {
70        match self {
71            Self::Component(c) => Some(&mut c.props),
72            Self::Unit(u) => u.props_mut(),
73            _ => None,
74        }
75    }
76
77    pub fn remap_props<F>(&mut self, f: F)
78    where
79        F: FnMut(Props) -> Props,
80    {
81        match self {
82            Self::Component(c) => c.remap_props(f),
83            Self::Unit(u) => u.remap_props(f),
84            _ => {}
85        }
86    }
87
88    pub fn shared_props(&self) -> Option<&Props> {
89        match self {
90            Self::Component(c) => c.shared_props.as_ref(),
91            _ => None,
92        }
93    }
94
95    pub fn shared_props_mut(&mut self) -> Option<&mut Props> {
96        match self {
97            Self::Component(c) => {
98                if c.shared_props.is_none() {
99                    c.shared_props = Some(Default::default());
100                }
101                c.shared_props.as_mut()
102            }
103            _ => None,
104        }
105    }
106
107    pub fn remap_shared_props<F>(&mut self, f: F)
108    where
109        F: FnMut(Props) -> Props,
110    {
111        if let Self::Component(c) = self {
112            c.remap_shared_props(f);
113        }
114    }
115
116    pub fn pack_tuple<const N: usize>(data: [WidgetNode; N]) -> Self {
117        Self::Tuple(data.into())
118    }
119
120    pub fn unpack_tuple<const N: usize>(self) -> [WidgetNode; N] {
121        if let WidgetNode::Tuple(mut data) = self {
122            let mut iter = data.drain(..);
123            std::array::from_fn(|_| iter.next().unwrap_or_default())
124        } else {
125            std::array::from_fn(|_| WidgetNode::None)
126        }
127    }
128}
129
130impl From<()> for WidgetNode {
131    fn from(_: ()) -> Self {
132        Self::None
133    }
134}
135
136impl From<()> for Box<WidgetNode> {
137    fn from(_: ()) -> Self {
138        Box::new(WidgetNode::None)
139    }
140}
141
142impl From<WidgetComponent> for WidgetNode {
143    fn from(component: WidgetComponent) -> Self {
144        Self::Component(component)
145    }
146}
147
148impl From<WidgetUnitNode> for WidgetNode {
149    fn from(unit: WidgetUnitNode) -> Self {
150        Self::Unit(unit)
151    }
152}
153
154impl From<WidgetUnitNode> for Box<WidgetNode> {
155    fn from(unit: WidgetUnitNode) -> Self {
156        Box::new(WidgetNode::Unit(unit))
157    }
158}
159
160impl<const N: usize> From<[WidgetNode; N]> for WidgetNode {
161    fn from(data: [WidgetNode; N]) -> Self {
162        Self::pack_tuple(data)
163    }
164}
165
166#[derive(Debug, Default, Clone, Serialize, Deserialize)]
167pub(crate) enum WidgetNodePrefab {
168    #[default]
169    None,
170    Component(WidgetComponentPrefab),
171    Unit(WidgetUnitNodePrefab),
172    Tuple(Vec<WidgetNodePrefab>),
173}
174
175impl Prefab for WidgetNodePrefab {}