darklua_core/rules/convert_require/
roblox_index_style.rs1use serde::{Deserialize, Serialize};
2
3use crate::nodes::{FieldExpression, FunctionCall, IndexExpression, Prefix, StringExpression};
4use crate::process::utils::is_valid_identifier;
5
6use std::str::FromStr;
7
8#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
10#[serde(rename_all = "snake_case", tag = "name")]
11pub enum RobloxIndexStyle {
12 #[default]
14 FindFirstChild,
15 WaitForChild,
17 Property,
19}
20
21impl RobloxIndexStyle {
22 pub(crate) fn index(&self, instance: Prefix, child_name: &str) -> Prefix {
23 let child_name = if child_name.ends_with(".lua") {
24 child_name.get(0..child_name.len() - 4).unwrap()
25 } else if child_name.ends_with(".luau") {
26 child_name.get(0..child_name.len() - 5).unwrap()
27 } else {
28 child_name
29 };
30 match self {
31 RobloxIndexStyle::FindFirstChild => FunctionCall::from_prefix(instance)
32 .with_method("FindFirstChild")
33 .with_argument(StringExpression::from_value(child_name))
34 .into(),
35 RobloxIndexStyle::WaitForChild => FunctionCall::from_prefix(instance)
36 .with_method("WaitForChild")
37 .with_argument(StringExpression::from_value(child_name))
38 .into(),
39 RobloxIndexStyle::Property => {
40 if is_valid_identifier(child_name) {
41 FieldExpression::new(instance, child_name).into()
42 } else {
43 IndexExpression::new(instance, StringExpression::from_value(child_name)).into()
44 }
45 }
46 }
47 }
48}
49
50impl FromStr for RobloxIndexStyle {
51 type Err = String;
52
53 fn from_str(s: &str) -> Result<Self, Self::Err> {
54 Ok(match s {
55 "find_first_child" => Self::FindFirstChild,
56 "wait_for_child" => Self::WaitForChild,
57 "property" => Self::Property,
58 _ => return Err(format!("invalid roblox index style `{}`", s)),
59 })
60 }
61}
62
63#[cfg(test)]
64mod test {
65 use super::*;
66
67 #[test]
68 fn deserialize_find_first_child() {
69 assert_eq!(
70 RobloxIndexStyle::FindFirstChild,
71 "find_first_child".parse().unwrap()
72 );
73 }
74
75 #[test]
76 fn deserialize_wait_for_child() {
77 assert_eq!(
78 RobloxIndexStyle::WaitForChild,
79 "wait_for_child".parse().unwrap()
80 );
81 }
82
83 #[test]
84 fn deserialize_property() {
85 assert_eq!(RobloxIndexStyle::Property, "property".parse().unwrap());
86 }
87
88 #[test]
89 fn deserialize_invalid() {
90 assert_eq!(
91 "invalid roblox index style `oops`",
92 "oops".parse::<RobloxIndexStyle>().unwrap_err()
93 );
94 }
95}