xenon_codegen/
identifier.rs

1use 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}