mago_syntax/ast/ast/
identifier.rs1use serde::Serialize;
2use strum::Display;
3
4use mago_span::HasSpan;
5use mago_span::Span;
6
7#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
11#[serde(tag = "type", content = "value")]
12#[repr(u8)]
13pub enum Identifier<'arena> {
14 Local(LocalIdentifier<'arena>),
15 Qualified(QualifiedIdentifier<'arena>),
16 FullyQualified(FullyQualifiedIdentifier<'arena>),
17}
18
19#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
23pub struct LocalIdentifier<'arena> {
24 pub span: Span,
25 pub value: &'arena str,
26}
27
28#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
32pub struct QualifiedIdentifier<'arena> {
33 pub span: Span,
34 pub value: &'arena str,
35}
36
37#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
41pub struct FullyQualifiedIdentifier<'arena> {
42 pub span: Span,
43 pub value: &'arena str,
44}
45
46impl<'arena> Identifier<'arena> {
47 #[inline]
48 #[must_use]
49 pub const fn is_local(&self) -> bool {
50 matches!(self, Identifier::Local(_))
51 }
52
53 #[inline]
54 #[must_use]
55 pub const fn is_qualified(&self) -> bool {
56 matches!(self, Identifier::Qualified(_))
57 }
58
59 #[inline]
60 #[must_use]
61 pub const fn is_fully_qualified(&self) -> bool {
62 matches!(self, Identifier::FullyQualified(_))
63 }
64
65 #[inline]
66 #[must_use]
67 pub const fn value(&self) -> &'arena str {
68 match &self {
69 Identifier::Local(local_identifier) => local_identifier.value,
70 Identifier::Qualified(qualified_identifier) => qualified_identifier.value,
71 Identifier::FullyQualified(fully_qualified_identifier) => fully_qualified_identifier.value,
72 }
73 }
74
75 #[inline]
76 #[must_use]
77 pub fn last_segment(&self) -> &'arena str {
78 let value = self.value();
79
80 match value.rfind('\\') {
81 Some(pos) => &value[pos + 1..],
82 None => value,
83 }
84 }
85}
86
87impl HasSpan for Identifier<'_> {
88 fn span(&self) -> Span {
89 match self {
90 Identifier::Local(local) => local.span(),
91 Identifier::Qualified(qualified) => qualified.span(),
92 Identifier::FullyQualified(fully_qualified) => fully_qualified.span(),
93 }
94 }
95}
96
97impl HasSpan for LocalIdentifier<'_> {
98 fn span(&self) -> Span {
99 self.span
100 }
101}
102
103impl HasSpan for QualifiedIdentifier<'_> {
104 fn span(&self) -> Span {
105 self.span
106 }
107}
108
109impl HasSpan for FullyQualifiedIdentifier<'_> {
110 fn span(&self) -> Span {
111 self.span
112 }
113}