1use std::borrow::Borrow;
2use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
3use std::fmt::Display;
4use std::hash::Hasher;
5use std::{cmp::Ordering, hash::Hash};
6
7pub use pax_lang::interpreter::{PaxExpression, PaxIdentifier, PaxPrimary};
8use pax_lang::DependencyCollector;
9use pax_message::serde::{Deserialize, Serialize};
10pub use pax_runtime_api;
11use pax_runtime_api::{CoercionRules, HelperFunctions, Interpolatable, PaxValue, ToPaxValue};
12pub mod parsing;
13pub mod server;
14
15#[cfg(feature = "parsing")]
16pub mod utils;
17
18pub mod cartridge_generation;
19pub mod code_serialization;
20pub mod constants;
21
22#[serde_with::serde_as]
24#[derive(Serialize, Deserialize, Clone)]
25#[serde(crate = "pax_message::serde")]
26pub struct PaxManifest {
27 #[serde_as(as = "BTreeMap<serde_with::json::JsonString, _>")]
28 pub components: BTreeMap<TypeId, ComponentDefinition>,
29 pub main_component_type_id: TypeId,
30 #[serde_as(as = "HashMap<serde_with::json::JsonString, _>")]
31 pub type_table: TypeTable,
32 pub assets_dirs: Vec<String>,
35 pub engine_import_path: String,
38}
39
40impl PaxManifest {
41 pub fn is_designer(&self) -> bool {
42 if let Some(identifier) = self.main_component_type_id.get_pascal_identifier() {
43 return identifier == "PaxDesigner";
44 }
45 false
46 }
47
48 pub fn get_template_node(
49 &self,
50 uni: &UniqueTemplateNodeIdentifier,
51 ) -> Option<&TemplateNodeDefinition> {
52 self.components
53 .get(&uni.component)?
54 .template
55 .as_ref()?
56 .nodes
57 .get(&uni.template_node_id)
58 }
59
60 pub fn get_all_component_property_definitions(
61 &self,
62 type_id: &TypeId,
63 ) -> Vec<PropertyDefinition> {
64 if let None = self.components.get(type_id) {
65 return Vec::default();
66 }
67 let mut common_properties = get_common_properties_as_property_definitions();
68 common_properties.extend(
69 self.type_table
70 .get(type_id)
71 .map(|table| table.property_definitions.clone())
72 .unwrap_or_default(),
73 );
74 common_properties
75 }
76
77 pub fn get_node_location(&self, uni: &UniqueTemplateNodeIdentifier) -> Option<NodeLocation> {
78 self.components
79 .get(&uni.component)
80 .unwrap()
81 .template
82 .as_ref()
83 .unwrap()
84 .get_location(&uni.template_node_id)
85 }
86
87 pub fn get_all_property_names(&self, type_id: &TypeId) -> HashSet<String> {
88 let mut ret = HashSet::new();
89 self.get_all_component_property_definitions(type_id)
90 .iter()
91 .for_each(|prop| {
92 ret.insert(prop.name.clone());
93 });
94 ret
95 }
96
97 pub fn get_main_cartridge_struct_id(&self) -> String {
100 format!(
101 "{}{}",
102 &self.main_component_type_id.get_pascal_identifier().unwrap(),
103 crate::constants::CARTRIDGE_PARTIAL_STRUCT_ID
104 )
105 }
106
107 pub fn get_main_definition_to_instance_traverser_struct_id(&self) -> String {
110 format!(
111 "{}{}",
112 &self.main_component_type_id.get_pascal_identifier().unwrap(),
113 crate::constants::DEFINITION_TO_INSTANCE_TRAVERSER_PARTIAL_STRUCT_ID
114 )
115 }
116
117 pub fn merge_in_place(&mut self, other: &PaxManifest) {
118 self.components.extend(other.components.clone());
119 self.type_table.extend(other.type_table.clone());
120 self.assets_dirs.extend(other.assets_dirs.clone());
121 }
122}
123
124pub fn get_common_properties_type_ids() -> Vec<TypeId> {
125 let mut ret = vec![];
126 for (_, import_path) in constants::COMMON_PROPERTIES_TYPE {
127 if SUPPORTED_NUMERIC_PRIMITIVES.contains(import_path)
128 || SUPPORTED_NONNUMERIC_PRIMITIVES.contains(import_path)
129 {
130 ret.push(TypeId::build_primitive(import_path));
131 } else {
132 ret.push(TypeId::build_singleton(import_path, None));
133 }
134 }
135 ret
136}
137
138pub fn get_common_properties_as_property_definitions() -> Vec<PropertyDefinition> {
139 let mut ret = vec![];
140 for (cp, import_path) in constants::COMMON_PROPERTIES_TYPE {
141 if SUPPORTED_NUMERIC_PRIMITIVES.contains(import_path)
142 || SUPPORTED_NONNUMERIC_PRIMITIVES.contains(import_path)
143 {
144 ret.push(PropertyDefinition {
145 name: cp.to_string(),
146 flags: Default::default(),
147 type_id: TypeId::build_primitive(import_path),
148 });
149 } else {
150 ret.push(PropertyDefinition {
151 name: cp.to_string(),
152 flags: Default::default(),
153 type_id: TypeId::build_singleton(import_path, None),
154 });
155 }
156 }
157 ret
158}
159
160pub const SUPPORTED_NUMERIC_PRIMITIVES: [&str; 13] = [
161 "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize", "f64",
162];
163
164pub const SUPPORTED_NONNUMERIC_PRIMITIVES: [&str; 2] = ["String", "bool"];
165
166#[derive(Serialize, Deserialize, Clone)]
169#[serde(crate = "pax_message::serde")]
170pub struct ComponentDefinition {
171 pub type_id: TypeId,
172 pub is_main_component: bool,
173 pub is_primitive: bool,
174
175 pub is_struct_only_component: bool,
178
179 pub module_path: String,
180
181 pub primitive_instance_import_path: Option<String>,
186 pub template: Option<ComponentTemplate>,
187 pub settings: Option<Vec<SettingsBlockElement>>,
188}
189
190impl ComponentDefinition {
191 pub fn get_property_definitions<'a>(&self, tt: &'a TypeTable) -> &'a Vec<PropertyDefinition> {
192 &tt.get(&self.type_id).unwrap().property_definitions
193 }
194}
195
196#[derive(Serialize, Deserialize, Debug, Clone)]
197#[serde(crate = "pax_message::serde")]
198pub enum SettingsBlockElement {
199 SelectorBlock(Token, LiteralBlockDefinition),
200 Handler(Token, Vec<Token>),
201 Comment(String),
202}
203
204#[derive(Serialize, Default, Deserialize, Debug, Clone, Hash, PartialEq, Eq)]
205#[serde(crate = "pax_message::serde")]
206pub struct TemplateNodeId(usize);
207
208impl CoercionRules for TemplateNodeId {
209 fn try_coerce(value: PaxValue) -> Result<Self, String> {
210 match value {
211 PaxValue::Numeric(_) => Ok(TemplateNodeId(usize::try_coerce(value)?)),
212 _ => Err("Cannot coerce PaxValue into TemplateNodeId".to_string()),
213 }
214 }
215}
216
217impl HelperFunctions for TemplateNodeId {}
218
219impl ToPaxValue for TemplateNodeId {
220 fn to_pax_value(self) -> PaxValue {
221 self.0.to_pax_value()
222 }
223}
224
225impl TemplateNodeId {
226 pub fn build(id: usize) -> Self {
227 TemplateNodeId(id)
228 }
229
230 pub fn as_usize(&self) -> usize {
231 self.0
232 }
233}
234
235impl Display for TemplateNodeId {
236 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
237 write!(f, "{}", self.0)
238 }
239}
240
241#[derive(Serialize, Default, Deserialize, Debug, Clone, Hash, PartialEq, Eq)]
242#[serde(crate = "pax_message::serde")]
243pub enum PaxType {
244 If,
245 Slot,
246 Repeat,
247 Comment,
248 BlankComponent {
249 pascal_identifier: String,
250 },
251 Primitive {
252 pascal_identifier: String,
253 },
254 Singleton {
255 pascal_identifier: String,
256 },
257 Range {
258 identifier: String,
259 },
260 Option {
261 identifier: String,
262 },
263 Vector {
264 elem_identifier: String,
265 },
266 Map {
267 key_identifier: String,
268 value_identifier: String,
269 },
270 #[default]
271 Unknown,
272}
273
274impl HelperFunctions for PaxType {}
275
276impl CoercionRules for PaxType {
277 fn try_coerce(value: PaxValue) -> Result<Self, String> {
278 match value {
279 PaxValue::Enum(_name, variant, args) => match variant.as_str() {
280 "If" => Ok(PaxType::If),
281 "Slot" => Ok(PaxType::Slot),
282 "Repeat" => Ok(PaxType::Repeat),
283 "Comment" => Ok(PaxType::Comment),
284 "BlankComponent" => {
285 let pascal_identifier = String::try_coerce(args[0].clone())?;
286 Ok(PaxType::BlankComponent { pascal_identifier })
287 }
288 "Primitive" => {
289 let pascal_identifier = String::try_coerce(args[0].clone())?;
290 Ok(PaxType::Primitive { pascal_identifier })
291 }
292 "Singleton" => {
293 let pascal_identifier = String::try_coerce(args[0].clone())?;
294 Ok(PaxType::Singleton { pascal_identifier })
295 }
296 "Range" => {
297 let identifier = String::try_coerce(args[0].clone())?;
298 Ok(PaxType::Range { identifier })
299 }
300 "Option" => {
301 let identifier = String::try_coerce(args[0].clone())?;
302 Ok(PaxType::Option { identifier })
303 }
304 "Vector" => {
305 let elem_identifier = String::try_coerce(args[0].clone())?;
306 Ok(PaxType::Vector { elem_identifier })
307 }
308 "Map" => {
309 let key_identifier = String::try_coerce(args[0].clone())?;
310 let value_identifier = String::try_coerce(args[1].clone())?;
311 Ok(PaxType::Map {
312 key_identifier,
313 value_identifier,
314 })
315 }
316 _ => Ok(PaxType::Unknown),
317 },
318 _ => Err("Cannot coerce PaxValue into PaxType".to_string()),
319 }
320 }
321}
322
323impl ToPaxValue for PaxType {
324 fn to_pax_value(self) -> PaxValue {
325 match self {
326 PaxType::If => PaxValue::Enum("PaxType".to_string(), "If".to_string(), vec![]),
327 PaxType::Slot => PaxValue::Enum("PaxType".to_string(), "Slot".to_string(), vec![]),
328 PaxType::Repeat => PaxValue::Enum("PaxType".to_string(), "Repeat".to_string(), vec![]),
329 PaxType::Comment => {
330 PaxValue::Enum("PaxType".to_string(), "Comment".to_string(), vec![])
331 }
332 PaxType::BlankComponent { pascal_identifier } => PaxValue::Enum(
333 "PaxType".to_string(),
334 "BlankComponent".to_string(),
335 vec![pascal_identifier.to_pax_value()],
336 ),
337 PaxType::Primitive { pascal_identifier } => PaxValue::Enum(
338 "PaxType".to_string(),
339 "Primitive".to_string(),
340 vec![pascal_identifier.to_pax_value()],
341 ),
342 PaxType::Singleton { pascal_identifier } => PaxValue::Enum(
343 "PaxType".to_string(),
344 "Singleton".to_string(),
345 vec![pascal_identifier.to_pax_value()],
346 ),
347 PaxType::Range { identifier } => PaxValue::Enum(
348 "PaxType".to_string(),
349 "Range".to_string(),
350 vec![identifier.to_pax_value()],
351 ),
352 PaxType::Option { identifier } => PaxValue::Enum(
353 "PaxType".to_string(),
354 "Option".to_string(),
355 vec![identifier.to_pax_value()],
356 ),
357 PaxType::Vector { elem_identifier } => PaxValue::Enum(
358 "PaxType".to_string(),
359 "Vector".to_string(),
360 vec![elem_identifier.to_pax_value()],
361 ),
362 PaxType::Map {
363 key_identifier,
364 value_identifier,
365 } => PaxValue::Enum(
366 "PaxType".to_string(),
367 "Map".to_string(),
368 vec![
369 key_identifier.to_pax_value(),
370 value_identifier.to_pax_value(),
371 ],
372 ),
373 PaxType::Unknown => {
374 PaxValue::Enum("PaxType".to_string(), "Unknown".to_string(), vec![])
375 }
376 }
377 }
378}
379
380impl Display for PaxType {
381 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
382 match self {
383 PaxType::If => write!(f, "If"),
384 PaxType::Slot => write!(f, "Slot"),
385 PaxType::Repeat => write!(f, "Repeat"),
386 PaxType::Comment => write!(f, "Comment"),
387 PaxType::BlankComponent { pascal_identifier } => write!(f, "{}", pascal_identifier),
388 PaxType::Primitive { pascal_identifier } => write!(f, "{}", pascal_identifier),
389 PaxType::Singleton { pascal_identifier } => write!(f, "{}", pascal_identifier),
390 PaxType::Range { identifier } => write!(f, "std::ops::Range<{}>", identifier),
391 PaxType::Option { identifier } => write!(f, "std::option::Option<{}>", identifier),
392 PaxType::Vector { elem_identifier } => write!(f, "std::vec::Vec<{}>", elem_identifier),
393 PaxType::Map {
394 key_identifier,
395 value_identifier,
396 } => write!(
397 f,
398 "std::collections::HashMap<{}><{}>",
399 key_identifier, value_identifier
400 ),
401 PaxType::Unknown => write!(f, "Unknown"),
402 }
403 }
404}
405
406#[derive(Serialize, Default, Deserialize, Debug, Clone, Hash, PartialEq, Eq)]
407#[serde(crate = "pax_message::serde")]
408pub struct TypeId {
409 pax_type: PaxType,
410 import_path: Option<String>,
411 is_intoable_downstream_type: bool,
412
413 _type_id: String,
414 _type_id_escaped: String,
415}
416
417impl HelperFunctions for TypeId {}
418
419impl PartialOrd for TypeId {
420 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
421 self._type_id.partial_cmp(&other._type_id)
422 }
423}
424
425impl CoercionRules for TypeId {
426 fn try_coerce(value: PaxValue) -> Result<Self, String> {
427 match value {
428 PaxValue::Object(map) => {
429 let pax_type = PaxType::try_coerce(
430 map.iter()
431 .find_map(|(n, v)| (n == "pax_type").then_some(v))
432 .unwrap()
433 .clone(),
434 )?;
435 let import_path = map
436 .iter()
437 .find_map(|(n, v)| (n == "import_path").then_some(v))
438 .map(|v| Option::<String>::try_coerce(v.clone()))
439 .unwrap_or(Ok(None))?;
440 let is_intoable_downstream_type = map
441 .iter()
442 .find_map(|(n, v)| (n == "is_intoable_downstream_type").then_some(v))
443 .map(|v| bool::try_coerce(v.clone()))
444 .unwrap_or(Ok(false))?;
445 let _type_id = map
446 .iter()
447 .find_map(|(n, v)| (n == "_type_id").then_some(v))
448 .map(|v| String::try_coerce(v.clone()))
449 .unwrap_or(Ok("".to_string()))?;
450 let _type_id_escaped = map
451 .iter()
452 .find_map(|(n, v)| (n == "_type_id_escaped").then_some(v))
453 .map(|v| String::try_coerce(v.clone()))
454 .unwrap_or(Ok("".to_string()))?;
455 Ok(Self {
456 pax_type,
457 import_path,
458 is_intoable_downstream_type,
459 _type_id,
460 _type_id_escaped,
461 })
462 }
463 _ => Err("Cannot coerce PaxValue into TypeId".to_string()),
464 }
465 }
466}
467
468impl ToPaxValue for TypeId {
469 fn to_pax_value(self) -> PaxValue {
470 let mut map = vec![];
471 map.push(("pax_type".to_string(), self.pax_type.to_pax_value()));
472 map.push(("import_path".to_string(), self.import_path.to_pax_value()));
473 map.push((
474 "is_intoable_downstream_type".to_string(),
475 self.is_intoable_downstream_type.to_pax_value(),
476 ));
477 map.push(("_type_id".to_string(), self._type_id.to_pax_value()));
478 map.push((
479 "_type_id_escaped".to_string(),
480 self._type_id_escaped.to_pax_value(),
481 ));
482 PaxValue::Object(map)
483 }
484}
485
486impl Ord for TypeId {
487 fn cmp(&self, other: &Self) -> Ordering {
488 self._type_id.cmp(&other._type_id)
489 }
490}
491
492impl Interpolatable for TypeId {}
493impl Interpolatable for TemplateNodeId {}
494
495impl Display for TypeId {
496 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
497 write!(f, "{}", self.get_unique_identifier())
498 }
499}
500
501impl TypeId {
502 pub fn build_if() -> Self {
503 TypeId {
504 pax_type: PaxType::If,
505 import_path: None,
506 is_intoable_downstream_type: false,
507 _type_id: "If".to_string(),
508 _type_id_escaped: "If".to_string(),
509 }
510 }
511
512 pub fn build_repeat() -> Self {
513 TypeId {
514 pax_type: PaxType::Repeat,
515 import_path: None,
516 is_intoable_downstream_type: false,
517 _type_id: "Repeat".to_string(),
518 _type_id_escaped: "Repeat".to_string(),
519 }
520 }
521
522 pub fn build_slot() -> Self {
523 TypeId {
524 pax_type: PaxType::Slot,
525 import_path: None,
526 is_intoable_downstream_type: false,
527 _type_id: "Slot".to_string(),
528 _type_id_escaped: "Slot".to_string(),
529 }
530 }
531
532 pub fn build_comment() -> Self {
533 TypeId {
534 pax_type: PaxType::Comment,
535 import_path: None,
536 is_intoable_downstream_type: false,
537 _type_id: "Comment".to_string(),
538 _type_id_escaped: "Comment".to_string(),
539 }
540 }
541
542 pub fn build_blank_component(pascal_identifier: &str) -> Self {
544 TypeId {
545 pax_type: PaxType::BlankComponent {
546 pascal_identifier: pascal_identifier.to_owned(),
547 },
548 import_path: None,
549 is_intoable_downstream_type: false,
550 _type_id: pascal_identifier.to_owned(),
551 _type_id_escaped: escape_identifier(pascal_identifier.to_owned()),
552 }
553 }
554
555 pub fn build_singleton(import_path: &str, pascal_identifier: Option<&str>) -> Self {
557 let pascal_identifier = if let Some(p) = pascal_identifier {
558 p.to_owned()
559 } else {
560 import_path.split("::").last().unwrap().to_string()
561 };
562
563 Self {
564 pax_type: PaxType::Singleton { pascal_identifier },
565 import_path: Some(import_path.to_owned()),
566 is_intoable_downstream_type: crate::constants::is_intoable_downstream_type(import_path),
567 _type_id: import_path.to_owned(),
568 _type_id_escaped: escape_identifier(import_path.to_owned()),
569 }
570 }
571
572 pub fn build_primitive(identifier: &str) -> Self {
574 TypeId {
575 pax_type: PaxType::Primitive {
576 pascal_identifier: identifier.to_owned(),
577 },
578 import_path: None,
579 is_intoable_downstream_type: crate::constants::is_intoable_downstream_type(identifier),
580 _type_id: identifier.to_owned(),
581 _type_id_escaped: identifier.to_owned(),
582 }
583 }
584
585 pub fn build_vector(elem_identifier: &str) -> Self {
587 let _id = format!("std::vec::Vec<{}>", elem_identifier);
588 Self {
589 pax_type: PaxType::Vector {
590 elem_identifier: elem_identifier.to_owned(),
591 },
592 import_path: Some("std::vec::Vec".to_string()),
593 is_intoable_downstream_type: false,
594 _type_id: _id.clone(),
595 _type_id_escaped: escape_identifier(_id),
596 }
597 }
598
599 pub fn build_range(identifier: &str) -> Self {
601 let _id = format!("std::ops::Range<{}>", identifier);
602 Self {
603 pax_type: PaxType::Range {
604 identifier: identifier.to_owned(),
605 },
606 import_path: Some("std::ops::Range".to_string()),
607 is_intoable_downstream_type: false,
608 _type_id: _id.clone(),
609 _type_id_escaped: escape_identifier(_id),
610 }
611 }
612
613 pub fn build_option(identifier: &str) -> Self {
615 let _id = format!("std::option::Option<{}>", identifier);
616 Self {
617 pax_type: PaxType::Option {
618 identifier: identifier.to_owned(),
619 },
620 import_path: Some("std::option::Option".to_string()),
621 is_intoable_downstream_type: false,
622 _type_id: _id.clone(),
623 _type_id_escaped: escape_identifier(_id),
624 }
625 }
626
627 pub fn build_map(key_identifier: &str, value_identifier: &str) -> Self {
629 let _id = format!(
630 "std::collections::HashMap<{}><{}>",
631 key_identifier.to_owned(),
632 value_identifier.to_owned()
633 );
634 Self {
635 pax_type: PaxType::Map {
636 key_identifier: key_identifier.to_owned(),
637 value_identifier: value_identifier.to_owned(),
638 },
639 import_path: Some("std::collections::HashMap".to_string()),
640 is_intoable_downstream_type: false,
641 _type_id: _id.clone(),
642 _type_id_escaped: escape_identifier(_id),
643 }
644 }
645
646 pub fn import_path(&self) -> Option<String> {
647 if let PaxType::Primitive { pascal_identifier } = &self.pax_type {
648 return Some(pascal_identifier.clone());
649 }
650 self.import_path.clone()
651 }
652
653 pub fn get_pascal_identifier(&self) -> Option<String> {
654 match &self.pax_type {
655 PaxType::Primitive { pascal_identifier }
656 | PaxType::Singleton { pascal_identifier }
657 | PaxType::BlankComponent { pascal_identifier } => Some(pascal_identifier.clone()),
658 PaxType::If | PaxType::Slot | PaxType::Repeat | PaxType::Comment => {
659 Some(self.pax_type.to_string())
660 }
661 _ => None,
662 }
663 }
664
665 pub fn get_unique_identifier(&self) -> String {
666 self._type_id.clone()
667 }
668
669 pub fn get_pax_type(&self) -> &PaxType {
670 self.pax_type.borrow()
671 }
672
673 pub fn get_snake_case_id(&self) -> String {
674 self.get_unique_identifier()
675 .replace("::", "_")
676 .replace("/", "_")
677 .replace("\\", "_")
678 .replace(">", "_")
679 .replace("<", "_")
680 .replace(".", "_")
681 }
682
683 pub fn is_blank_component(&self) -> bool {
684 if let PaxType::BlankComponent { .. } = self.pax_type {
685 true
686 } else {
687 false
688 }
689 }
690}
691
692impl Interpolatable for UniqueTemplateNodeIdentifier {}
693
694#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq, Default)]
695#[serde(crate = "pax_message::serde")]
696pub struct UniqueTemplateNodeIdentifier {
697 component: TypeId,
698 template_node_id: TemplateNodeId,
699}
700
701impl UniqueTemplateNodeIdentifier {
702 pub fn build(component: TypeId, template_node_id: TemplateNodeId) -> Self {
703 UniqueTemplateNodeIdentifier {
704 component,
705 template_node_id,
706 }
707 }
708
709 pub fn get_containing_component_type_id(&self) -> TypeId {
710 self.component.clone()
711 }
712
713 pub fn get_template_node_id(&self) -> TemplateNodeId {
714 self.template_node_id.clone()
715 }
716}
717
718impl Display for UniqueTemplateNodeIdentifier {
719 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
720 write!(f, "({}, {})", self.component, self.template_node_id)
721 }
722}
723
724#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]
725pub enum TreeLocation {
726 #[default]
727 Root,
728 Parent(TemplateNodeId),
729}
730
731#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]
732pub enum TreeIndexPosition {
733 #[default]
734 Top,
735 Bottom,
736 At(usize),
737}
738
739impl TreeIndexPosition {
740 pub fn get_index(&self, len: usize) -> usize {
741 match self {
742 TreeIndexPosition::Top => 0,
743 TreeIndexPosition::Bottom => len,
744 TreeIndexPosition::At(index) => *index,
745 }
746 }
747
748 pub fn new(index: usize) -> Self {
749 TreeIndexPosition::At(index)
750 }
751}
752
753impl PartialOrd for TreeIndexPosition {
754 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
755 match self {
756 TreeIndexPosition::Top => match other {
757 TreeIndexPosition::Top => Some(Ordering::Equal),
758 TreeIndexPosition::Bottom => Some(Ordering::Less),
759 TreeIndexPosition::At(_) => Some(Ordering::Less),
760 },
761 TreeIndexPosition::Bottom => match other {
762 TreeIndexPosition::Top => Some(Ordering::Greater),
763 TreeIndexPosition::Bottom => Some(Ordering::Equal),
764 TreeIndexPosition::At(_) => Some(Ordering::Less),
765 },
766 TreeIndexPosition::At(index) => match other {
767 TreeIndexPosition::Top => Some(Ordering::Greater),
768 TreeIndexPosition::Bottom => Some(Ordering::Greater),
769 TreeIndexPosition::At(other_index) => index.partial_cmp(other_index),
770 },
771 }
772 }
773}
774
775impl Ord for TreeIndexPosition {
776 fn cmp(&self, other: &Self) -> Ordering {
777 self.partial_cmp(other).unwrap()
778 }
779}
780
781#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]
782pub struct NodeLocation {
783 pub type_id: TypeId,
784 pub tree_location: TreeLocation,
785 pub index: TreeIndexPosition,
786}
787
788impl NodeLocation {
789 pub fn new(type_id: TypeId, location: TreeLocation, index: TreeIndexPosition) -> Self {
790 NodeLocation {
791 type_id,
792 tree_location: location,
793 index,
794 }
795 }
796
797 pub fn get_tree_location(&self) -> &TreeLocation {
798 &self.tree_location
799 }
800
801 pub fn get_type_id(&self) -> &TypeId {
802 &self.type_id
803 }
804
805 pub fn root(type_id: TypeId) -> Self {
806 NodeLocation {
807 type_id,
808 tree_location: TreeLocation::Root,
809 index: TreeIndexPosition::Top,
810 }
811 }
812
813 pub fn parent(type_id: TypeId, parent: TemplateNodeId) -> Self {
814 NodeLocation {
815 type_id,
816 tree_location: TreeLocation::Parent(parent),
817 index: TreeIndexPosition::Top,
818 }
819 }
820
821 pub fn set_index(&mut self, index: TreeIndexPosition) {
822 self.index = index;
823 }
824}
825
826impl PartialOrd for NodeLocation {
827 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
828 match self.tree_location {
829 TreeLocation::Root => match other.tree_location {
830 TreeLocation::Root => {
831 return self.index.partial_cmp(&other.index);
832 }
833 TreeLocation::Parent(_) => {
834 return Some(Ordering::Less);
835 }
836 },
837 TreeLocation::Parent(_) => match other.tree_location {
838 TreeLocation::Root => {
839 return Some(Ordering::Greater);
840 }
841 TreeLocation::Parent(_) => {
842 return self.index.partial_cmp(&other.index);
843 }
844 },
845 }
846 }
847}
848
849impl Ord for NodeLocation {
850 fn cmp(&self, other: &Self) -> Ordering {
851 self.partial_cmp(other).unwrap()
852 }
853}
854
855#[serde_with::serde_as]
856#[derive(Serialize, Deserialize, Debug, Clone, Default)]
857#[serde(crate = "pax_message::serde")]
858pub struct ComponentTemplate {
859 containing_component: TypeId,
860 root: VecDeque<TemplateNodeId>,
861 #[serde_as(as = "HashMap<serde_with::json::JsonString, _>")]
862 children: HashMap<TemplateNodeId, VecDeque<TemplateNodeId>>,
863 #[serde_as(as = "HashMap<serde_with::json::JsonString, _>")]
864 nodes: HashMap<TemplateNodeId, TemplateNodeDefinition>,
865 next_id: usize,
866 template_source_file_path: Option<String>,
867}
868
869impl ComponentTemplate {
870 pub fn new(containing_component: TypeId, template_source_file_path: Option<String>) -> Self {
871 Self {
872 containing_component,
873 root: VecDeque::new(),
874 children: HashMap::new(),
875 nodes: HashMap::new(),
876 next_id: 0,
877 template_source_file_path,
878 }
879 }
880
881 pub fn get_containing_component_type_id(&self) -> TypeId {
882 self.containing_component.clone()
883 }
884
885 pub fn get_next_id(&self) -> usize {
886 self.next_id
887 }
888
889 pub fn set_next_id(&mut self, id: usize) {
890 self.next_id = id;
891 }
892
893 pub fn get_file_path(&self) -> Option<String> {
894 self.template_source_file_path.clone()
895 }
896
897 pub fn get_unique_identifier(&self, id: TemplateNodeId) -> UniqueTemplateNodeIdentifier {
898 let type_id = self.containing_component.clone();
899 UniqueTemplateNodeIdentifier::build(type_id, id)
900 }
901
902 pub fn contains_slots(&self) -> bool {
903 self.nodes
904 .values()
905 .any(|v| v.type_id.pax_type == PaxType::Slot)
906 }
907
908 fn consume_next_id(&mut self) -> TemplateNodeId {
909 let current_next_id = self.next_id;
910 self.next_id = self.next_id + 1;
911 TemplateNodeId::build(current_next_id)
912 }
913
914 pub fn add_at(
915 &mut self,
916 tnd: TemplateNodeDefinition,
917 location: NodeLocation,
918 ) -> UniqueTemplateNodeIdentifier {
919 match location.get_tree_location() {
920 TreeLocation::Root => match location.index {
921 TreeIndexPosition::Top => {
922 return self.add_root_node_front(tnd);
923 }
924 TreeIndexPosition::Bottom => {
925 return self.add_root_node_back(tnd);
926 }
927 TreeIndexPosition::At(index) => {
928 return self.add_root_node_at(index, tnd);
929 }
930 },
931 TreeLocation::Parent(p) => match location.index {
932 TreeIndexPosition::Top => {
933 return self.add_child_front(p.clone(), tnd);
934 }
935 TreeIndexPosition::Bottom => {
936 return self.add_child_back(p.clone(), tnd);
937 }
938 TreeIndexPosition::At(index) => {
939 return self.add_child_at(p.clone(), index, tnd);
940 }
941 },
942 }
943 }
944
945 pub fn add_root_node_front(
946 &mut self,
947 tnd: TemplateNodeDefinition,
948 ) -> UniqueTemplateNodeIdentifier {
949 let id = self.consume_next_id();
950 self.root.push_front(id.clone());
951 self.nodes.insert(id.clone(), tnd);
952 self.get_unique_identifier(id)
953 }
954
955 pub fn add_root_node_back(
956 &mut self,
957 tnd: TemplateNodeDefinition,
958 ) -> UniqueTemplateNodeIdentifier {
959 let id = self.consume_next_id();
960 self.root.push_back(id.clone());
961 self.nodes.insert(id.clone(), tnd);
962 self.get_unique_identifier(id)
963 }
964
965 pub fn add_root_node_at(
966 &mut self,
967 index: usize,
968 tnd: TemplateNodeDefinition,
969 ) -> UniqueTemplateNodeIdentifier {
970 let id = self.consume_next_id();
971 self.root.insert(index, id.clone());
972 self.children
973 .entry(id.clone())
974 .or_insert_with(VecDeque::new);
975 self.nodes.insert(id.clone(), tnd);
976 self.get_unique_identifier(id)
977 }
978
979 pub fn add(&mut self, tnd: TemplateNodeDefinition) -> UniqueTemplateNodeIdentifier {
980 self.add_root_node_front(tnd)
981 }
982
983 pub fn add_child_front(
984 &mut self,
985 id: TemplateNodeId,
986 tnd: TemplateNodeDefinition,
987 ) -> UniqueTemplateNodeIdentifier {
988 if let Some(_) = self.nodes.get_mut(&id) {
989 let child_id = self.consume_next_id();
990 if let Some(children) = self.children.get_mut(&id) {
991 children.push_front(child_id.clone());
992 self.nodes.insert(child_id.clone(), tnd);
993 } else {
994 let mut children = VecDeque::new();
995 children.push_front(child_id.clone());
996 self.nodes.insert(child_id.clone(), tnd);
997 self.children.insert(id, children);
998 }
999 self.get_unique_identifier(child_id)
1000 } else {
1001 panic!("Invalid parent");
1002 }
1003 }
1004
1005 pub fn add_child_back(
1006 &mut self,
1007 id: TemplateNodeId,
1008 tnd: TemplateNodeDefinition,
1009 ) -> UniqueTemplateNodeIdentifier {
1010 if let Some(_) = self.nodes.get_mut(&id) {
1011 let child_id = self.consume_next_id();
1012 if let Some(children) = self.children.get_mut(&id) {
1013 children.push_back(child_id.clone());
1014 self.nodes.insert(child_id.clone(), tnd);
1015 } else {
1016 let mut children = VecDeque::new();
1017 children.push_back(child_id.clone());
1018 self.nodes.insert(child_id.clone(), tnd);
1019 self.children.insert(id, children);
1020 }
1021 self.get_unique_identifier(child_id)
1022 } else {
1023 panic!("Invalid parent");
1024 }
1025 }
1026
1027 pub fn add_child_at(
1028 &mut self,
1029 id: TemplateNodeId,
1030 index: usize,
1031 tnd: TemplateNodeDefinition,
1032 ) -> UniqueTemplateNodeIdentifier {
1033 if let Some(_) = self.nodes.get_mut(&id) {
1034 let child_id = self.consume_next_id();
1035 if let Some(children) = self.children.get_mut(&id) {
1036 children.insert(index, child_id.clone());
1037 self.nodes.insert(child_id.clone(), tnd);
1038 } else {
1039 let mut children = VecDeque::new();
1040 children.insert(index, child_id.clone());
1041 self.nodes.insert(child_id.clone(), tnd);
1042 self.children.insert(id, children);
1043 }
1044 self.get_unique_identifier(child_id)
1045 } else {
1046 panic!("Invalid parent");
1047 }
1048 }
1049
1050 pub fn add_child(
1051 &mut self,
1052 id: TemplateNodeId,
1053 tnd: TemplateNodeDefinition,
1054 ) -> UniqueTemplateNodeIdentifier {
1055 self.add_child_front(id, tnd)
1056 }
1057
1058 pub fn remove_node(&mut self, id: TemplateNodeId) -> TemplateNodeDefinition {
1059 if let Some(tnd) = self.nodes.get(&id) {
1060 let node = tnd.clone();
1061 let subtree = self.get_subtree(&id);
1062 for node in subtree {
1063 self.nodes.remove(&node);
1064 self.children.remove(&node);
1065 for (_, children) in self.children.iter_mut() {
1066 children.retain(|child| *child != node);
1067 }
1068 }
1069 self.nodes.remove(&id);
1070 self.children.remove(&id);
1071 for c in self.children.values_mut() {
1072 c.retain(|v| v != &id);
1073 }
1074 self.root.retain(|child| *child != id);
1075 node
1076 } else {
1077 panic!("Requested node doesn't exist in template");
1078 }
1079 }
1080
1081 fn get_subtree(&self, id: &TemplateNodeId) -> Vec<TemplateNodeId> {
1082 let mut ret = vec![];
1083 if let Some(children) = self.children.get(&id) {
1084 for child in children {
1085 ret.push(child.clone());
1086 ret.extend(self.get_subtree(child));
1087 }
1088 }
1089 ret
1090 }
1091
1092 pub fn get_root(&self) -> Vec<TemplateNodeId> {
1093 self.root.clone().into()
1094 }
1095
1096 pub fn get_children(&self, id: &TemplateNodeId) -> Option<Vec<TemplateNodeId>> {
1097 if let Some(c) = self.children.get(&id) {
1098 return Some(c.clone().into());
1099 }
1100 None
1101 }
1102
1103 pub fn get_parent(&self, id: &TemplateNodeId) -> Option<TemplateNodeId> {
1104 if self.root.contains(id) {
1105 return None;
1106 }
1107 self.children
1108 .iter()
1109 .find_map(|(n_id, child_ids)| child_ids.contains(&id).then_some(n_id).cloned())
1110 }
1111
1112 pub fn get_node(&self, id: &TemplateNodeId) -> Option<&TemplateNodeDefinition> {
1113 self.nodes.get(id)
1114 }
1115
1116 pub fn set_node(&mut self, id: TemplateNodeId, tnd: TemplateNodeDefinition) {
1117 self.nodes.insert(id, tnd);
1118 }
1119
1120 pub fn update_node_type_id(&mut self, id: &TemplateNodeId, new_type: &TypeId) {
1121 if let Some(node) = self.nodes.get_mut(id) {
1122 node.type_id = new_type.clone();
1123 }
1124 }
1125
1126 pub fn update_node_properties(
1127 &mut self,
1128 id: &TemplateNodeId,
1129 mut properties: HashMap<Token, Option<ValueDefinition>>,
1130 ) {
1131 if let Some(node) = self.nodes.get_mut(id) {
1132 if let Some(settings) = &mut node.settings {
1133 let mut indexes_to_remove: Vec<usize> = vec![];
1134 for (i, setting) in settings.iter_mut().enumerate() {
1135 if let SettingElement::Setting(key, v) = setting {
1136 if let Some(new_value) = properties.remove(key) {
1137 if let Some(updated) = new_value {
1138 *v = updated;
1139 } else {
1140 indexes_to_remove.push(i);
1141 }
1142 }
1143 }
1144 }
1145
1146 for i in indexes_to_remove.iter().rev() {
1148 settings.remove(*i);
1149 }
1150 } else {
1151 node.settings = Some(vec![]);
1152 }
1153 }
1154 for (k, v) in properties.iter() {
1156 if let Some(node) = self.nodes.get_mut(id) {
1157 if let Some(settings) = &mut node.settings {
1158 if let Some(value) = v {
1159 settings.push(SettingElement::Setting(k.clone(), value.clone()));
1160 }
1161 }
1162 }
1163 }
1164 }
1165
1166 pub fn update_classes(&mut self, id: &TemplateNodeId, classes: HashMap<String, bool>) {
1167 if let Some(node) = self.nodes.get_mut(id) {
1168 if let Some(settings) = &mut node.settings {
1169 let mut indexes_to_remove: Vec<usize> = vec![];
1170 for (i, setting) in settings.iter_mut().enumerate() {
1171 if let SettingElement::Setting(key, value) = setting {
1172 if &key.token_value == "class" {
1173 if let ValueDefinition::Identifier(value) = value {
1174 if !*classes.get(&format!(".{}", value.name)).unwrap_or(&true) {
1175 indexes_to_remove.push(i);
1176 }
1177 }
1178 }
1179 if &key.token_value == "id" {
1180 if let ValueDefinition::Identifier(value) = value {
1181 if !*classes.get(&format!("#{}", value.name)).unwrap_or(&true) {
1182 indexes_to_remove.push(i);
1183 }
1184 }
1185 }
1186 }
1187 }
1188 for i in indexes_to_remove.iter().rev() {
1190 settings.remove(*i);
1191 }
1192 } else {
1193 node.settings = Some(vec![]);
1194 }
1195 }
1196 for (k, v) in classes.iter() {
1198 if let Some(node) = self.nodes.get_mut(id) {
1199 if let Some(settings) = &mut node.settings {
1200 if *v {
1201 let is_class = k.starts_with('.');
1202 let key = if is_class { "class" } else { "id" }.to_string();
1203 settings.push(SettingElement::Setting(
1204 Token::new_without_location(key),
1205 ValueDefinition::Identifier(PaxIdentifier {
1206 name: k
1207 .trim_start_matches('.')
1208 .trim_start_matches('#')
1209 .to_string(),
1210 }),
1211 ));
1212 }
1213 }
1214 }
1215 }
1216 }
1217
1218 pub fn update_control_flow_properties(
1219 &mut self,
1220 id: &TemplateNodeId,
1221 repeat_predicate_definition: Option<Option<ControlFlowRepeatPredicateDefinition>>,
1222 repeat_source_expression: Option<Option<ExpressionInfo>>,
1223 conditional_expression: Option<Option<ExpressionInfo>>,
1224 slot_index_expression: Option<Option<ExpressionInfo>>,
1225 ) {
1226 let Some(control_flow_settings) = self
1227 .nodes
1228 .get_mut(id)
1229 .and_then(|n| n.control_flow_settings.as_mut())
1230 else {
1231 return;
1232 };
1233 if let Some(value) = repeat_predicate_definition {
1234 control_flow_settings.repeat_predicate_definition = value;
1235 }
1236 if let Some(value) = repeat_source_expression {
1237 control_flow_settings.repeat_source_expression = value;
1238 }
1239 if let Some(value) = conditional_expression {
1240 control_flow_settings.condition_expression = value;
1241 }
1242 if let Some(value) = slot_index_expression {
1243 control_flow_settings.slot_index_expression = value;
1244 }
1245 }
1246
1247 pub fn find_node_with_str_id(&self, id: &str) -> Option<&TemplateNodeId> {
1248 for (i, n) in &self.nodes {
1249 if let Some(settings) = &n.settings {
1250 for setting in settings {
1251 if let SettingElement::Setting(setting, value) = setting {
1252 if setting.token_value == "id" {
1253 if let ValueDefinition::LiteralValue(val) = value {
1254 if let PaxValue::String(val_id) = val {
1255 if id == val_id {
1256 return Some(i);
1257 }
1258 };
1259 }
1260 }
1261 }
1262 }
1263 }
1264 }
1265 None
1266 }
1267
1268 pub fn get_nodes(&self) -> Vec<&TemplateNodeDefinition> {
1269 self.nodes.values().collect()
1270 }
1271
1272 pub fn get_nodes_mut(&mut self) -> Vec<&mut TemplateNodeDefinition> {
1273 self.nodes.values_mut().collect()
1274 }
1275
1276 pub fn get_nodes_owned(&self) -> Vec<TemplateNodeDefinition> {
1277 self.nodes.values().map(|x| x.clone()).collect()
1278 }
1279
1280 pub fn get_ids(&self) -> Vec<&TemplateNodeId> {
1281 self.nodes.keys().collect()
1282 }
1283
1284 pub fn get_location(&self, id: &TemplateNodeId) -> Option<NodeLocation> {
1285 if self.root.contains(&id) {
1286 let mut node_location = NodeLocation::root(self.containing_component.clone());
1287 node_location.set_index(TreeIndexPosition::new(
1288 self.root.iter().position(|x| *x == *id).unwrap(),
1289 ));
1290 return Some(node_location);
1291 }
1292 for (parent, children) in self.children.iter() {
1293 if children.contains(&id) {
1294 let mut node_location =
1295 NodeLocation::parent(self.containing_component.clone(), parent.clone());
1296 node_location.set_index(TreeIndexPosition::new(
1297 children.iter().position(|x| *x == *id).unwrap(),
1298 ));
1299 return Some(node_location);
1300 }
1301 }
1302 None
1303 }
1304
1305 pub fn detach_node(&mut self, id: &TemplateNodeId) -> NodeLocation {
1306 let current_location = self
1307 .get_location(id)
1308 .expect("Node doesn't exist in template");
1309 let parent = match current_location.get_tree_location() {
1310 TreeLocation::Root => {
1311 self.root.retain(|root_node| *root_node != *id);
1312 return current_location;
1313 }
1314 TreeLocation::Parent(parent) => parent,
1315 };
1316 let children = self.children.get_mut(&parent).unwrap();
1317 children.retain(|child| *child != *id);
1318 current_location
1319 }
1320
1321 pub fn get_siblings(&self, id: &TemplateNodeId) -> Option<VecDeque<TemplateNodeId>> {
1322 if self.root.contains(id) {
1323 Some(self.root.clone())
1324 } else {
1325 Some(self.children.values().find(|&v| v.contains(id)).cloned()?)
1326 }
1327 }
1328
1329 pub fn move_node(&mut self, id: &TemplateNodeId, new_location: NodeLocation) {
1330 self.detach_node(id);
1331 let (target_list, index) = match new_location.get_tree_location() {
1332 TreeLocation::Root => (&mut self.root, new_location.index),
1333 TreeLocation::Parent(p) => (
1334 self.children.entry(p.clone()).or_default(),
1335 new_location.index,
1336 ),
1337 };
1338 let index = match index {
1339 TreeIndexPosition::Top => 0,
1340 TreeIndexPosition::Bottom => target_list.len(),
1341 TreeIndexPosition::At(i) => i,
1342 };
1343 target_list.insert(index.clamp(0, target_list.len()), id.clone());
1344 }
1345
1346 pub fn get_all_children_relationships(
1347 &self,
1348 ) -> HashMap<TemplateNodeId, VecDeque<TemplateNodeId>> {
1349 self.children.clone()
1350 }
1351
1352 pub fn merge_with_settings(&mut self, settings_block: &Option<Vec<SettingsBlockElement>>) {
1353 for node in self.get_nodes_mut() {
1354 node.settings = PaxManifest::merge_inline_settings_with_settings_block(
1355 &mut node.settings,
1356 settings_block,
1357 );
1358 }
1359 }
1360}
1361
1362#[derive(Serialize, Deserialize, Default, Debug, Clone)]
1367#[serde(crate = "pax_message::serde")]
1368pub struct TemplateNodeDefinition {
1369 pub type_id: TypeId,
1371 pub control_flow_settings: Option<ControlFlowSettingsDefinition>,
1373 pub settings: Option<Vec<SettingElement>>,
1375 pub raw_comment_string: Option<String>,
1377}
1378
1379impl TemplateNodeDefinition {
1380 pub fn get_node_type(&self) -> NodeType {
1381 if let Some(cfsd) = &self.control_flow_settings {
1382 NodeType::ControlFlow(Box::new(cfsd.clone()))
1383 } else if let Some(settings) = &self.settings {
1384 NodeType::Template(settings.clone())
1385 } else if let Some(comment) = &self.raw_comment_string {
1386 NodeType::Comment(comment.clone())
1387 } else {
1388 panic!("Invalid TemplateNodeDefinition");
1389 }
1390 }
1391}
1392
1393#[derive(Serialize, Deserialize, Clone, Debug)]
1394pub enum NodeType {
1395 Template(Vec<SettingElement>),
1396 ControlFlow(Box<ControlFlowSettingsDefinition>),
1397 Comment(String),
1398}
1399
1400pub type TypeTable = HashMap<TypeId, TypeDefinition>;
1401pub fn get_primitive_type_table() -> TypeTable {
1402 let mut ret: TypeTable = Default::default();
1403
1404 SUPPORTED_NUMERIC_PRIMITIVES.into_iter().for_each(|snp| {
1405 ret.insert(TypeId::build_primitive(snp), TypeDefinition::primitive(snp));
1406 });
1407 SUPPORTED_NONNUMERIC_PRIMITIVES
1408 .into_iter()
1409 .for_each(|snnp| {
1410 ret.insert(
1411 TypeId::build_primitive(snnp),
1412 TypeDefinition::primitive(snnp),
1413 );
1414 });
1415
1416 ret
1417}
1418
1419#[derive(Serialize, Deserialize, Debug, Clone, Default)]
1420#[serde(crate = "pax_message::serde")]
1421pub struct PropertyDefinition {
1422 pub name: String,
1424
1425 pub flags: PropertyDefinitionFlags,
1429
1430 pub type_id: TypeId,
1432}
1433
1434impl PropertyDefinition {
1435 pub fn get_type_definition<'a>(&'a self, tt: &'a TypeTable) -> &TypeDefinition {
1436 if let None = tt.get(&self.type_id) {
1437 panic!("TypeTable does not contain type_id: {}", &self.type_id);
1438 }
1439 tt.get(&self.type_id).unwrap()
1440 }
1441
1442 pub fn get_inner_iterable_type_definition<'a>(
1443 &'a self,
1444 tt: &'a TypeTable,
1445 ) -> Option<&TypeDefinition> {
1446 if let Some(ref iiti) = tt.get(&self.type_id).unwrap().inner_iterable_type_id {
1447 Some(tt.get(iiti).unwrap())
1448 } else {
1449 None
1450 }
1451 }
1452}
1453
1454#[derive(Serialize, Deserialize, Debug, Clone, Default)]
1458#[serde(crate = "pax_message::serde")]
1459pub struct PropertyDefinitionFlags {
1460 pub is_binding_repeat_i: bool,
1465 pub is_binding_repeat_elem: bool,
1467
1468 pub is_repeat_source_range: bool,
1473 pub is_repeat_source_iterable: bool,
1475
1476 pub is_property_wrapped: bool,
1480
1481 pub is_enum: bool,
1483}
1484
1485impl PropertyDefinition {
1489 pub fn primitive_with_name(type_name: &str, symbol_name: &str) -> Self {
1491 PropertyDefinition {
1492 name: symbol_name.to_string(),
1493 flags: PropertyDefinitionFlags::default(),
1494 type_id: TypeId::build_primitive(type_name),
1495 }
1496 }
1497}
1498
1499#[derive(Serialize, Deserialize, Clone, Default)]
1501#[serde(crate = "pax_message::serde")]
1502pub struct TypeDefinition {
1503 pub type_id: TypeId,
1505
1506 pub inner_iterable_type_id: Option<TypeId>,
1509
1510 pub property_definitions: Vec<PropertyDefinition>,
1512}
1513
1514impl TypeDefinition {
1515 pub fn primitive(type_name: &str) -> Self {
1516 Self {
1517 type_id: TypeId::build_primitive(type_name),
1518 property_definitions: vec![],
1519 inner_iterable_type_id: None,
1520 }
1521 }
1522
1523 pub fn builtin_vec_rc_ref_cell_any_properties(inner_iterable_type_id: TypeId) -> Self {
1525 Self {
1526 type_id: TypeId::build_vector("std::rc::Rc<core::cell::RefCell<PaxAny>>"),
1527 property_definitions: vec![],
1528 inner_iterable_type_id: Some(inner_iterable_type_id),
1529 }
1530 }
1531
1532 pub fn builtin_range_isize() -> Self {
1533 Self {
1534 type_id: TypeId::build_range("isize"),
1535 property_definitions: vec![],
1536 inner_iterable_type_id: Some(TypeId::build_primitive("isize")),
1537 }
1538 }
1539}
1540
1541#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq)]
1542pub struct ExpressionCompilationInfo {
1543 pub vtable_id: usize,
1544 pub dependencies: Vec<String>,
1546}
1547
1548#[derive(Serialize, Deserialize, Default, Debug, Clone)]
1551#[serde(crate = "pax_message::serde")]
1552pub enum ValueDefinition {
1553 #[default]
1554 Undefined, LiteralValue(PaxValue),
1556 Block(LiteralBlockDefinition),
1557 Expression(ExpressionInfo),
1559 Identifier(PaxIdentifier),
1561 DoubleBinding(PaxIdentifier),
1563 EventBindingTarget(PaxIdentifier),
1564}
1565
1566impl Display for ValueDefinition {
1567 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1568 match self {
1569 ValueDefinition::Undefined => write!(f, "<undefined>"),
1570 ValueDefinition::LiteralValue(value) => write!(f, "{}", value),
1571 ValueDefinition::Block(block) => write!(f, "{}", block),
1572 ValueDefinition::Expression(e) => write!(f, "{{{}}}", e.expression),
1573 ValueDefinition::Identifier(i) => write!(f, "{}", i),
1574 ValueDefinition::DoubleBinding(ident) => {
1575 write!(f, "bind:{}", ident)
1576 }
1577 ValueDefinition::EventBindingTarget(ident) => {
1578 write!(f, "@<event-binding>={}", ident)
1579 }
1580 }
1581 }
1582}
1583
1584#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
1587#[serde(crate = "pax_message::serde")]
1588pub struct LocationInfo {
1589 pub start_line_col: (usize, usize),
1590 pub end_line_col: (usize, usize),
1591}
1592
1593#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
1597#[serde(crate = "pax_message::serde")]
1598pub enum ControlFlowRepeatPredicateDefinition {
1599 ElemId(String),
1600 ElemIdIndexId(String, String),
1601}
1602
1603impl ControlFlowRepeatPredicateDefinition {
1604 pub fn get_symbols(&self) -> HashSet<String> {
1605 match self {
1606 ControlFlowRepeatPredicateDefinition::ElemId(t) => {
1607 vec![t.clone()].into_iter().collect()
1608 }
1609 ControlFlowRepeatPredicateDefinition::ElemIdIndexId(t1, t2) => {
1610 vec![t1.clone(), t2.clone()].into_iter().collect()
1611 }
1612 }
1613 }
1614}
1615
1616#[derive(Serialize, Deserialize, Debug, Clone, Default)]
1620#[serde(crate = "pax_message::serde")]
1621pub struct ControlFlowSettingsDefinition {
1622 pub condition_expression: Option<ExpressionInfo>,
1623 pub slot_index_expression: Option<ExpressionInfo>,
1624 pub repeat_predicate_definition: Option<ControlFlowRepeatPredicateDefinition>,
1625 pub repeat_source_expression: Option<ExpressionInfo>,
1626}
1627
1628#[derive(Serialize, Deserialize, Debug, Clone, Default)]
1629#[serde(crate = "pax_message::serde")]
1630pub struct ExpressionInfo {
1631 pub expression: PaxExpression,
1632 pub dependencies: Vec<String>,
1633}
1634
1635impl Display for ExpressionInfo {
1636 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1637 write!(f, "{}", self.expression)
1638 }
1639}
1640
1641impl ExpressionInfo {
1642 pub fn new(expr: PaxExpression) -> Self {
1643 Self {
1644 dependencies: expr.collect_dependencies(),
1645 expression: expr,
1646 }
1647 }
1648}
1649
1650#[derive(Serialize, Deserialize, Debug, Clone, Default)]
1652#[serde(crate = "pax_message::serde")]
1653pub struct LiteralBlockDefinition {
1654 pub explicit_type_pascal_identifier: Option<Token>,
1655 pub elements: Vec<SettingElement>,
1656}
1657
1658impl Display for LiteralBlockDefinition {
1659 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1660 let elements = &self.elements;
1661 write!(f, "{{")?;
1662 for e in elements {
1663 match e {
1664 SettingElement::Setting(Token { token_value, .. }, value) => {
1665 write!(f, "{}: {} ", token_value, value)?;
1666 }
1667 SettingElement::Comment(_) => (),
1668 }
1669 }
1670 write!(f, "}}")?;
1671 Ok(())
1672 }
1673}
1674
1675impl LiteralBlockDefinition {
1676 pub fn new(elements: Vec<SettingElement>) -> Self {
1677 Self {
1678 explicit_type_pascal_identifier: None,
1679 elements,
1680 }
1681 }
1682}
1683
1684#[derive(Serialize, Deserialize, Debug, Clone)]
1685#[serde(crate = "pax_message::serde")]
1686pub enum SettingElement {
1687 Setting(Token, ValueDefinition),
1688 Comment(String),
1689}
1690
1691impl LiteralBlockDefinition {
1692 pub fn get_all_settings<'a>(&'a self) -> Vec<(&'a Token, &'a ValueDefinition)> {
1693 self.elements
1694 .iter()
1695 .filter_map(|lbe| {
1696 if let SettingElement::Setting(t, vd) = lbe {
1697 Some((t, vd))
1698 } else {
1699 None
1700 }
1701 })
1702 .collect()
1703 }
1704}
1705
1706#[derive(Serialize, Deserialize, Debug, Clone, Default, Eq)]
1709#[serde(crate = "pax_message::serde")]
1710pub struct Token {
1711 pub token_value: String,
1712 pub token_location: Option<LocationInfo>,
1713}
1714
1715impl PartialEq for Token {
1716 fn eq(&self, other: &Self) -> bool {
1717 self.token_value == other.token_value
1718 }
1719}
1720
1721impl Hash for Token {
1722 fn hash<H: Hasher>(&self, state: &mut H) {
1723 self.token_value.hash(state)
1724 }
1725}
1726
1727impl PartialOrd for Token {
1728 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1729 self.token_value.partial_cmp(&other.token_value)
1730 }
1731}
1732
1733impl Ord for Token {
1734 fn cmp(&self, other: &Self) -> Ordering {
1735 self.token_value.cmp(&other.token_value)
1736 }
1737}
1738
1739impl Token {
1740 pub fn new(token_value: String, token_location: LocationInfo) -> Self {
1741 Self {
1742 token_value,
1743 token_location: Some(token_location),
1744 }
1745 }
1746
1747 pub fn new_without_location(token_value: String) -> Self {
1748 Self {
1749 token_value,
1750 token_location: None,
1751 }
1752 }
1753}
1754
1755#[derive(Serialize, Deserialize, Debug, Clone)]
1756#[serde(crate = "pax_message::serde")]
1757pub enum Number {
1758 Float(f64),
1759 Int(isize),
1760}
1761
1762#[derive(Serialize, Deserialize, Debug, Clone)]
1763#[serde(crate = "pax_message::serde")]
1764pub enum Unit {
1765 Pixels,
1766 Percent,
1767}
1768
1769pub fn escape_identifier(input: String) -> String {
1770 input
1771 .replace("(", "LPAR")
1772 .replace("::", "COCO")
1773 .replace(")", "RPAR")
1774 .replace("<", "LABR")
1775 .replace(">", "RABR")
1776 .replace(",", "COMM")
1777 .replace(".", "PERI")
1778 .replace("[", "LSQB")
1779 .replace("]", "RSQB")
1780 .replace("/", "FSLA")
1781 .replace("\\", "BSLA")
1782 .replace("#", "HASH")
1783 .replace("-", "HYPH")
1784}
1785
1786pub struct HostCrateInfo {
1788 pub name: String,
1790 pub identifier: String,
1792 pub import_prefix: String,
1794}
1795
1796pub const IMPORTS_BUILTINS: &[&str] = &[
1798 "std::any::Any",
1799 "pax_runtime::api::{use_RefCell}",
1800 "std::collections::HashMap",
1801 "std::collections::VecDeque",
1802 "std::ops::Deref",
1803 "std::rc::Rc",
1804 "pax_runtime::RepeatItem",
1805 "pax_runtime::RepeatProperties",
1806 "pax_runtime::ConditionalProperties",
1807 "pax_runtime::Slot",
1808 "pax_runtime::api::Property",
1809 "pax_runtime::api::CommonProperties",
1810 "pax_runtime::api::Color::*",
1811 "pax_runtime::ComponentInstance",
1812 "pax_runtime::InstanceNodePtr",
1813 "pax_runtime::InstanceNodePtrList",
1814 "pax_runtime::ExpressionContext",
1815 "pax_runtime::PaxEngine",
1816 "pax_runtime::InstanceNode",
1817 "pax_runtime::HandlerRegistry",
1818 "pax_runtime::InstantiationArgs",
1819 "pax_runtime::ConditionalInstance",
1820 "pax_runtime::SlotInstance",
1821 "pax_runtime::properties::RuntimePropertiesStackFrame",
1822 "pax_runtime::repeat::RepeatInstance",
1823 "piet_common::RenderContext",
1824];