microcad_lang/lower/ir/identifier/
qualified_name.rs1use derive_more::{Deref, DerefMut};
5
6use microcad_lang_base::{Identifier, Refer, SrcRef, SrcReferrer};
7use microcad_lang_proc_macros::SrcReferrer;
8use miette::SourceSpan;
9
10#[derive(
13 Default, Clone, Debug, PartialEq, Hash, Eq, Ord, PartialOrd, DerefMut, Deref, SrcReferrer,
14)]
15pub struct QualifiedName(Refer<Vec<Identifier>>);
16
17#[derive(Debug, Deref)]
19pub struct QualifiedNames(Vec<QualifiedName>);
20
21impl std::fmt::Display for QualifiedNames {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 write!(
24 f,
25 "{}",
26 self.0
27 .iter()
28 .map(|name| name.to_string())
29 .collect::<Vec<_>>()
30 .join(", ")
31 )
32 }
33}
34
35impl FromIterator<QualifiedName> for QualifiedNames {
36 fn from_iter<T: IntoIterator<Item = QualifiedName>>(iter: T) -> Self {
37 Self(iter.into_iter().collect())
38 }
39}
40
41impl QualifiedName {
42 pub fn new(ids: Vec<Identifier>, src_ref: SrcRef) -> Self {
47 Self(Refer::new(ids, src_ref))
48 }
49
50 pub fn is_qualified(&self) -> bool {
52 self.0.len() > 1
53 }
54
55 pub fn is_within(&self, module: &QualifiedName) -> bool {
57 self.starts_with(module)
58 }
59
60 pub fn remove_first(&self) -> Self {
62 Self(Refer::new(self.0[1..].to_vec(), self.0.src_ref.clone()))
63 }
64
65 pub fn remove_last(self) -> Self {
67 Self(Refer::new(
68 self.0[..self.0.len() - 1].to_vec(),
69 self.0.src_ref.clone(),
70 ))
71 }
72
73 pub fn push(&mut self, id: Identifier) {
75 self.0.push(id)
76 }
77
78 pub fn split_first(&self) -> (Identifier, QualifiedName) {
80 match self.len() {
81 0 => todo!("return None or error?"),
82 1 => (self.0[0].clone(), Self::default()),
83 _ => (self.0[0].clone(), Self(Refer::none(self.0[1..].into()))),
84 }
85 }
86
87 pub fn with_prefix(&self, prefix: &QualifiedName) -> Self {
89 let mut full_name = prefix.clone();
90 full_name.append(&mut self.clone());
91 full_name
92 }
93}
94
95impl crate::lower::SingleIdentifier for QualifiedName {
96 fn single_identifier(&self) -> Option<&Identifier> {
97 if self.is_single_identifier() {
98 self.0.first()
99 } else {
100 None
101 }
102 }
103
104 fn is_single_identifier(&self) -> bool {
105 self.0.len() == 1
106 }
107}
108
109impl From<QualifiedName> for SourceSpan {
110 fn from(value: QualifiedName) -> Self {
111 value.src_ref().into()
112 }
113}
114
115impl From<Identifier> for QualifiedName {
116 fn from(id: Identifier) -> Self {
117 let src_ref = id.src_ref();
118 Self(Refer::new(vec![id], src_ref))
119 }
120}
121
122impl std::fmt::Display for QualifiedName {
123 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
124 if self.is_empty() {
125 write!(f, "NO NAME")
126 } else {
127 write!(
128 f,
129 "{}",
130 self.iter()
131 .map(|id| format!("{id}"))
132 .collect::<Vec<_>>()
133 .join("::")
134 )
135 }
136 }
137}
138
139impl From<Refer<Vec<Identifier>>> for QualifiedName {
140 fn from(value: Refer<Vec<Identifier>>) -> Self {
141 Self(value)
142 }
143}
144
145impl FromIterator<Identifier> for QualifiedName {
146 fn from_iter<T: IntoIterator<Item = Identifier>>(iter: T) -> Self {
147 Self(Refer::none(iter.into_iter().collect()))
148 }
149}
150
151impl From<&Identifier> for QualifiedName {
152 fn from(id: &Identifier) -> Self {
153 Self(Refer::none(vec![id.clone()]))
154 }
155}
156
157impl From<&str> for QualifiedName {
158 fn from(value: &str) -> Self {
159 Self(Refer::none(
160 value.split("::").map(Identifier::from).collect(),
161 ))
162 }
163}
164
165impl From<QualifiedName> for String {
166 fn from(value: QualifiedName) -> Self {
167 value
168 .iter()
169 .map(|id| format!("{id}"))
170 .collect::<Vec<_>>()
171 .join("::")
172 }
173}