darklua_core/rules/convert_require/
instance_path.rs1use crate::nodes::{FieldExpression, FunctionCall, Identifier, Prefix, StringExpression};
2
3use super::RobloxIndexStyle;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub(crate) struct InstancePath {
7 root: InstancePathRoot,
8 components: Vec<InstancePathComponent>,
9}
10
11impl InstancePath {
12 pub(crate) fn from_root() -> Self {
13 Self {
14 root: InstancePathRoot::Root,
15 components: Vec::new(),
16 }
17 }
18
19 pub(crate) fn from_script() -> Self {
20 Self {
21 root: InstancePathRoot::Script,
22 components: Vec::new(),
23 }
24 }
25
26 pub(crate) fn parent(&mut self) {
27 self.components.push(InstancePathComponent::Parent);
28 }
29
30 pub(crate) fn child(&mut self, child_name: impl Into<String>) {
31 self.components
32 .push(InstancePathComponent::Child(child_name.into()));
33 }
34
35 pub(crate) fn convert(&self, index_style: &RobloxIndexStyle) -> Prefix {
36 let mut components_iter = self.components.iter();
37
38 let mut prefix = match &self.root {
39 InstancePathRoot::Root => {
40 let mut prefix: Prefix = datamodel_identifier().into();
41 if let Some(InstancePathComponent::Child(service_name)) = components_iter.next() {
42 prefix = FunctionCall::from_prefix(prefix)
43 .with_method("GetService")
44 .with_argument(StringExpression::from_value(service_name))
45 .into();
46 }
47 prefix
48 }
49 InstancePathRoot::Script => script_identifier().into(),
50 };
51
52 for component in components_iter {
53 match component {
54 InstancePathComponent::Parent => {
55 prefix = get_parent_instance(prefix);
56 }
57 InstancePathComponent::Child(child_name) => {
58 prefix = index_style.index(prefix, child_name);
59 }
60 }
61 }
62
63 prefix
64 }
65}
66
67#[derive(Debug, Clone, PartialEq, Eq)]
68pub(crate) enum InstancePathRoot {
69 Root,
70 Script,
71}
72
73#[derive(Debug, Clone, PartialEq, Eq)]
74pub(crate) enum InstancePathComponent {
75 Parent,
76 Child(String),
77}
78
79pub(crate) fn script_identifier() -> Identifier {
80 Identifier::new("script")
81}
82
83pub(crate) fn datamodel_identifier() -> Identifier {
84 Identifier::new("game")
85}
86
87pub(crate) fn get_parent_instance(instance: impl Into<Prefix>) -> Prefix {
88 FieldExpression::new(instance.into(), "Parent").into()
89}