xenon_codegen/
identifier.rs1use core::fmt;
2
3use enum_as_inner::EnumAsInner;
4
5use crate::expression::Expression;
6
7#[derive(Debug, Clone, Default, EnumAsInner)]
8pub enum IdentifierAccess {
9 Access(Access),
10 DerefAccess(Access),
11 FunctionCall(FunctionCall),
12 #[default]
13 Null,
14}
15impl IdentifierAccess {
16 pub fn is_valid(&self) -> bool {
17 if self.is_access() {
18 self.as_access().unwrap().is_valid()
19 } else if self.is_deref_access() {
20 return self.as_deref_access().unwrap().is_valid();
21 } else if self.is_function_call() {
22 return self.as_function_call().unwrap().is_valid();
23 } else {
24 return false;
25 }
26 }
27}
28impl fmt::Display for IdentifierAccess {
29 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 if self.is_access() {
31 match write!(fmt, "{}", self.as_access().unwrap()) {
32 Ok(_) => (),
33 Err(e) => return Err(e),
34 }
35 } else if self.is_deref_access() {
36 match write!(fmt, "{}", self.as_deref_access().unwrap()) {
37 Ok(_) => (),
38 Err(e) => return Err(e),
39 }
40 } else if self.is_function_call() {
41 match write!(fmt, "{}", self.as_function_call().unwrap()) {
42 Ok(_) => (),
43 Err(e) => return Err(e),
44 }
45 }
46 Ok(())
47 }
48}
49
50#[derive(Debug, Clone)]
51pub struct Access {
52 pub name: String,
53 pub child: Option<Box<IdentifierAccess>>,
54}
55impl Access {
56 pub fn new(name: String) -> Access {
57 Access { name, child: None }
58 }
59
60 pub fn is_valid(&self) -> bool {
61 if self.name.is_empty() {
62 return false;
63 }
64 if self.child.is_some() {
65 return self.child.clone().unwrap().is_valid();
66 }
67 true
68 }
69}
70impl fmt::Display for Access {
71 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72 match write!(fmt, "{}", self.name) {
73 Ok(_) => (),
74 Err(e) => return Err(e),
75 }
76 if let Some(c) = self.child.clone() {
77 if c.is_access() {
78 match write!(fmt, ".{}", c.as_access().unwrap()) {
79 Ok(_) => (),
80 Err(e) => return Err(e),
81 }
82 } else if c.is_deref_access() {
83 match write!(fmt, "->{}", c.as_deref_access().unwrap()) {
84 Ok(_) => (),
85 Err(e) => return Err(e),
86 }
87 } else if c.is_function_call() {
88 match write!(fmt, ".{}", c.as_function_call().unwrap()) {
89 Ok(_) => (),
90 Err(e) => return Err(e),
91 }
92 }
93 }
94
95 Ok(())
96 }
97}
98
99#[derive(Debug, Clone)]
100pub struct FunctionCall {
101 pub name: String,
102 pub arguments: Vec<Expression>,
103 pub child: Option<Box<IdentifierAccess>>,
104}
105impl FunctionCall {
106 pub fn new(name: String, arguments: Vec<Expression>) -> FunctionCall {
107 FunctionCall {
108 name,
109 arguments,
110 child: None,
111 }
112 }
113
114 pub fn is_valid(&self) -> bool {
115 if self.name.is_empty() {
116 return false;
117 }
118 for i in 0..self.arguments.len() {
119 if !self.arguments[i].clone().is_valid() {
120 return false;
121 }
122 }
123 match self.child.clone() {
124 Some(c) => c.is_valid(),
125 None => true,
126 }
127 }
128}
129impl fmt::Display for FunctionCall {
130 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131 match write!(fmt, "{}(", self.name) {
132 Ok(_) => (),
133 Err(e) => return Err(e),
134 }
135 if !self.arguments.is_empty() {
136 match write!(fmt, "{}", self.arguments[0]) {
137 Ok(_) => (),
138 Err(e) => return Err(e),
139 }
140 }
141 for i in 1..self.arguments.len() {
142 match write!(fmt, ", {}", self.arguments[i]) {
143 Ok(_) => (),
144 Err(e) => return Err(e),
145 }
146 }
147 match write!(fmt, ")") {
148 Ok(_) => (),
149 Err(e) => return Err(e),
150 }
151 if let Some(c) = self.child.clone() {
152 if c.is_access() {
153 match write!(fmt, ".{}", c.as_access().unwrap()) {
154 Ok(_) => (),
155 Err(e) => return Err(e),
156 }
157 } else if c.is_deref_access() {
158 match write!(fmt, "->{}", c.as_deref_access().unwrap()) {
159 Ok(_) => (),
160 Err(e) => return Err(e),
161 }
162 } else if c.is_function_call() {
163 match write!(fmt, ".{}", c.as_function_call().unwrap()) {
164 Ok(_) => (),
165 Err(e) => return Err(e),
166 }
167 }
168 }
169 Ok(())
170 }
171}