darklua_core/nodes/
identifier.rs

1use crate::nodes::Token;
2
3use super::{Type, TypedIdentifier};
4
5#[derive(Clone, Debug, PartialEq, Eq)]
6pub struct Identifier {
7    name: String,
8    token: Option<Token>,
9}
10
11impl Identifier {
12    pub fn new<S: Into<String>>(name: S) -> Self {
13        Self {
14            name: name.into(),
15            token: None,
16        }
17    }
18
19    pub fn with_type(self, r#type: impl Into<Type>) -> TypedIdentifier {
20        TypedIdentifier::from(self).with_type(r#type.into())
21    }
22
23    pub fn with_token(mut self, token: Token) -> Self {
24        self.token = Some(token);
25        self
26    }
27
28    #[inline]
29    pub fn set_token(&mut self, token: Token) {
30        self.token = Some(token);
31    }
32
33    #[inline]
34    pub fn get_token(&self) -> Option<&Token> {
35        self.token.as_ref()
36    }
37
38    #[inline]
39    pub fn mutate_token(&mut self) -> Option<&mut Token> {
40        self.token.as_mut()
41    }
42
43    #[inline]
44    pub fn get_name(&self) -> &String {
45        &self.name
46    }
47
48    #[inline]
49    pub fn mutate_name(&mut self) -> &mut String {
50        &mut self.name
51    }
52
53    #[inline]
54    pub fn set_name<IntoString: Into<String>>(&mut self, name: IntoString) {
55        let name = name.into();
56        if let Some(token) = &mut self.token {
57            token.replace_with_content(name.clone());
58        }
59        self.name = name;
60    }
61
62    #[inline]
63    pub fn into_name(self) -> String {
64        self.name
65    }
66
67    super::impl_token_fns!(iter = [token]);
68}
69
70impl<IntoString: Into<String>> From<IntoString> for Identifier {
71    fn from(identifier: IntoString) -> Self {
72        Self {
73            name: identifier.into(),
74            token: None,
75        }
76    }
77}
78
79#[cfg(test)]
80mod test {
81    use crate::nodes::Position;
82
83    use super::*;
84
85    #[test]
86    fn set_name_replaces_the_token_content() {
87        let token = Token::new_with_line(7, 10, 1);
88        let mut identifier = Identifier::new("var").with_token(token);
89
90        identifier.set_name("newVar");
91
92        assert_eq!(
93            identifier.get_token().unwrap(),
94            &Token::from_position(Position::LineNumber {
95                line_number: 1,
96                content: "newVar".into(),
97            })
98        );
99    }
100}