1use serde::{Deserialize, Serialize};
2use slotmap::new_key_type;
3use indexmap::IndexMap;
4use std::sync::Arc;
5use crate::reactive::Binding;
6
7new_key_type! {
9 pub struct NodeId;
10}
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14pub enum Value {
15 Static(serde_json::Value),
17 Binding(Binding),
19 TemplateString {
22 template: String,
23 bindings: Vec<Binding>,
24 },
25 Action(String),
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
32pub enum IRNode {
33 Element(Element),
35
36 ForEach {
39 source: Binding,
41 item_name: String,
43 key_path: Option<String>,
45 template: Vec<IRNode>,
47 props: Props,
49 },
50
51 Conditional {
54 value: Value,
56 branches: Vec<ConditionalBranch>,
58 fallback: Option<Vec<IRNode>>,
60 },
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct ConditionalBranch {
66 pub pattern: Value,
68 pub children: Vec<IRNode>,
70}
71
72impl IRNode {
73 pub fn element(element: Element) -> Self {
75 IRNode::Element(element)
76 }
77
78 pub fn for_each(
80 source: Binding,
81 item_name: impl Into<String>,
82 key_path: Option<String>,
83 template: Vec<IRNode>,
84 props: Props,
85 ) -> Self {
86 IRNode::ForEach {
87 source,
88 item_name: item_name.into(),
89 key_path,
90 template,
91 props,
92 }
93 }
94
95 pub fn conditional(
97 value: Value,
98 branches: Vec<ConditionalBranch>,
99 fallback: Option<Vec<IRNode>>,
100 ) -> Self {
101 IRNode::Conditional {
102 value,
103 branches,
104 fallback,
105 }
106 }
107
108 pub fn as_element(&self) -> Option<&Element> {
110 match self {
111 IRNode::Element(e) => Some(e),
112 _ => None,
113 }
114 }
115
116 pub fn is_for_each(&self) -> bool {
118 matches!(self, IRNode::ForEach { .. })
119 }
120
121 pub fn is_conditional(&self) -> bool {
123 matches!(self, IRNode::Conditional { .. })
124 }
125}
126
127impl ConditionalBranch {
128 pub fn new(pattern: Value, children: Vec<IRNode>) -> Self {
130 Self { pattern, children }
131 }
132}
133
134pub type PropsMap = IndexMap<String, Value>;
136
137#[derive(Debug, Clone)]
142pub struct Props(Arc<PropsMap>);
143
144impl Props {
145 pub fn new() -> Self {
147 Props(Arc::new(IndexMap::new()))
148 }
149
150 pub fn from_map(map: PropsMap) -> Self {
152 Props(Arc::new(map))
153 }
154
155 pub fn make_mut(&mut self) -> &mut PropsMap {
159 Arc::make_mut(&mut self.0)
160 }
161
162 pub fn insert(&mut self, key: String, value: Value) -> Option<Value> {
164 self.make_mut().insert(key, value)
165 }
166
167 pub fn remove(&mut self, key: &str) -> Option<Value> {
169 self.make_mut().shift_remove(key)
170 }
171
172 pub fn inner(&self) -> &PropsMap {
174 &self.0
175 }
176}
177
178impl Default for Props {
179 fn default() -> Self {
180 Props::new()
181 }
182}
183
184impl std::ops::Deref for Props {
185 type Target = PropsMap;
186
187 fn deref(&self) -> &Self::Target {
188 &self.0
189 }
190}
191
192impl<'a> IntoIterator for &'a Props {
193 type Item = (&'a String, &'a Value);
194 type IntoIter = indexmap::map::Iter<'a, String, Value>;
195
196 fn into_iter(self) -> Self::IntoIter {
197 self.0.iter()
198 }
199}
200
201impl FromIterator<(String, Value)> for Props {
202 fn from_iter<I: IntoIterator<Item = (String, Value)>>(iter: I) -> Self {
203 Props(Arc::new(iter.into_iter().collect()))
204 }
205}
206
207impl serde::Serialize for Props {
209 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
210 where
211 S: serde::Serializer,
212 {
213 self.0.serialize(serializer)
214 }
215}
216
217impl<'de> serde::Deserialize<'de> for Props {
218 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
219 where
220 D: serde::Deserializer<'de>,
221 {
222 let map = PropsMap::deserialize(deserializer)?;
223 Ok(Props(Arc::new(map)))
224 }
225}
226
227#[derive(Debug, Clone, Serialize, Deserialize)]
232pub struct Element {
233 pub element_type: String,
235
236 pub props: Props,
238
239 #[serde(with = "arc_element_vec")]
241 pub children: im::Vector<Arc<Element>>,
242
243 pub key: Option<String>,
245}
246
247mod arc_element_vec {
249 use super::*;
250 use serde::{Deserializer, Serializer};
251
252 pub fn serialize<S>(vec: &im::Vector<Arc<Element>>, serializer: S) -> Result<S::Ok, S::Error>
253 where
254 S: Serializer,
255 {
256 use serde::ser::SerializeSeq;
257 let mut seq = serializer.serialize_seq(Some(vec.len()))?;
258 for elem in vec.iter() {
259 seq.serialize_element(elem.as_ref())?;
260 }
261 seq.end()
262 }
263
264 pub fn deserialize<'de, D>(deserializer: D) -> Result<im::Vector<Arc<Element>>, D::Error>
265 where
266 D: Deserializer<'de>,
267 {
268 let vec: Vec<Element> = Vec::deserialize(deserializer)?;
269 Ok(vec.into_iter().map(Arc::new).collect())
270 }
271}
272
273impl Element {
274 pub fn new(element_type: impl Into<String>) -> Self {
275 Self {
276 element_type: element_type.into(),
277 props: Props::new(),
278 children: im::Vector::new(),
279 key: None,
280 }
281 }
282
283 pub fn with_prop(mut self, key: impl Into<String>, value: Value) -> Self {
284 self.props.insert(key.into(), value);
285 self
286 }
287
288 pub fn with_child(mut self, child: Element) -> Self {
289 self.children.push_back(Arc::new(child));
290 self
291 }
292
293 pub fn with_arc_child(mut self, child: Arc<Element>) -> Self {
295 self.children.push_back(child);
296 self
297 }
298
299 pub fn with_key(mut self, key: impl Into<String>) -> Self {
300 self.key = Some(key.into());
301 self
302 }
303}