1use crate::parser::FileId;
2use crate::parser::LineColumn;
3use crate::parser::SourceMap;
4use crate::parser::SourceSpan;
5use std::fmt;
6use std::hash::Hash;
7use std::hash::Hasher;
8use std::ops::Range;
9use triomphe::HeaderSlice;
10
11#[derive(serde::Deserialize)]
23#[serde(from = "T")]
24pub struct Node<T: ?Sized>(triomphe::Arc<HeaderSlice<Header, T>>);
25
26#[derive(Clone)]
27struct Header {
28 location: Option<SourceSpan>,
29 extension_id: Option<ExtensionId>,
30}
31
32#[derive(Debug, Clone, Eq)]
37pub struct ExtensionId {
38 arc: triomphe::Arc<Option<SourceSpan>>,
39}
40
41impl ExtensionId {
42 pub fn new<T>(extension: &Node<T>) -> Self {
43 Self {
44 arc: triomphe::Arc::new(extension.location()),
45 }
46 }
47
48 pub fn location(&self) -> Option<SourceSpan> {
51 *self.arc
52 }
53
54 pub fn same_location<T>(&self, node: T) -> Node<T> {
55 Node::new_opt_location(node, self.location())
56 }
57}
58
59impl PartialEq for ExtensionId {
60 fn eq(&self, other: &Self) -> bool {
61 triomphe::Arc::ptr_eq(&self.arc, &other.arc)
62 }
63}
64
65impl Hash for ExtensionId {
66 fn hash<H: Hasher>(&self, state: &mut H) {
67 triomphe::Arc::as_ptr(&self.arc).hash(state);
68 }
69}
70
71impl<T> Node<T> {
72 #[inline]
74 pub fn new_parsed(node: T, location: SourceSpan) -> Self {
75 Self::new_opt_location(node, Some(location))
76 }
77
78 pub fn new(node: T) -> Self {
80 Self::new_opt_location(node, None)
81 }
82
83 pub(crate) fn new_opt_location(node: T, location: Option<SourceSpan>) -> Self {
84 Self(triomphe::Arc::new(HeaderSlice {
85 header: Header {
86 location,
87 extension_id: None,
88 },
89 slice: node,
90 }))
91 }
92
93 pub fn with_extension_id(&self, id: ExtensionId) -> Self
96 where
97 T: Clone,
98 {
99 Self(triomphe::Arc::new(HeaderSlice {
100 header: Header {
101 location: self.location(),
102 extension_id: Some(id),
103 },
104 slice: self.0.slice.clone(),
105 }))
106 }
107
108 pub fn set_extension_id(&mut self, id: ExtensionId)
113 where
114 T: Clone,
115 {
116 if self.extension_id() != Some(&id) {
117 triomphe::Arc::make_mut(&mut self.0).header.extension_id = Some(id);
118 }
119 }
120}
121
122impl Node<str> {
123 #[inline]
125 pub fn new_str_parsed(node: &str, location: SourceSpan) -> Self {
126 Self::new_str_opt_location(node, Some(location))
127 }
128
129 pub fn new_str(node: &str) -> Self {
131 Self::new_str_opt_location(node, None)
132 }
133
134 pub(crate) fn new_str_opt_location(node: &str, location: Option<SourceSpan>) -> Self {
135 Self(triomphe::Arc::from_header_and_str(
136 Header {
137 location,
138 extension_id: None,
139 },
140 node,
141 ))
142 }
143
144 pub fn as_str(&self) -> &str {
145 self
146 }
147}
148
149impl<T: ?Sized> Node<T> {
150 pub fn location(&self) -> Option<SourceSpan> {
153 self.0.header.location
154 }
155
156 pub fn extension_id(&self) -> Option<&ExtensionId> {
161 self.0.header.extension_id.as_ref()
162 }
163
164 pub fn is_built_in(&self) -> bool {
167 self.location().map(|l| l.file_id()) == Some(FileId::BUILT_IN)
168 }
169
170 pub fn line_column_range(&self, sources: &SourceMap) -> Option<Range<LineColumn>> {
172 self.location()?.line_column_range(sources)
173 }
174
175 pub fn same_location<U>(&self, node: U) -> Node<U> {
177 Node::new_opt_location(node, self.0.header.location)
178 }
179
180 pub fn ptr_eq(&self, other: &Self) -> bool {
184 triomphe::Arc::ptr_eq(&self.0, &other.0)
185 }
186
187 pub fn make_mut(&mut self) -> &mut T
201 where
202 T: Clone,
203 {
204 let inner = triomphe::Arc::make_mut(&mut self.0);
205 &mut inner.slice
208 }
209
210 pub fn get_mut(&mut self) -> Option<&mut T> {
212 triomphe::Arc::get_mut(&mut self.0).map(|inner| &mut inner.slice)
213 }
214}
215
216impl<T: ?Sized> std::ops::Deref for Node<T> {
217 type Target = T;
218
219 fn deref(&self) -> &Self::Target {
220 &self.0.slice
221 }
222}
223
224impl<T: ?Sized> Clone for Node<T> {
225 fn clone(&self) -> Self {
226 Self(self.0.clone())
227 }
228}
229
230impl<T: Default> Default for Node<T> {
231 fn default() -> Self {
232 Self::new(T::default())
233 }
234}
235
236impl<T: ?Sized + fmt::Debug> fmt::Debug for Node<T> {
237 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
238 if let Some(location) = self.location() {
239 write!(f, "{location:?} ")?
240 }
241 if let Some(id) = self.extension_id() {
242 match id.location() {
243 Some(location) => write!(f, "(extension {location:?}) ")?,
244 None => write!(f, "(extension) ")?,
245 }
246 }
247 self.0.slice.fmt(f)
248 }
249}
250
251impl<T: ?Sized + fmt::Display> fmt::Display for Node<T> {
252 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
253 T::fmt(self, f)
254 }
255}
256
257impl<T: ?Sized + Eq> Eq for Node<T> {}
258
259impl<T: ?Sized + PartialEq> PartialEq for Node<T> {
260 fn eq(&self, other: &Self) -> bool {
261 self.ptr_eq(other) || self.0.slice == other.0.slice }
264}
265
266impl<T: ?Sized + Hash> Hash for Node<T> {
267 fn hash<H: Hasher>(&self, state: &mut H) {
268 self.0.slice.hash(state)
269 }
270}
271
272impl<T: ?Sized> std::borrow::Borrow<T> for Node<T> {
273 fn borrow(&self) -> &T {
274 self
275 }
276}
277
278impl<T: ?Sized> AsRef<T> for Node<T> {
279 fn as_ref(&self) -> &T {
280 self
281 }
282}
283
284impl<T> From<T> for Node<T> {
285 fn from(node: T) -> Self {
286 Self::new(node)
287 }
288}
289
290impl From<&'_ str> for Node<str> {
291 fn from(node: &'_ str) -> Self {
292 Self::new_str(node)
293 }
294}
295
296impl From<&'_ String> for Node<str> {
297 fn from(node: &'_ String) -> Self {
298 Self::new_str(node)
299 }
300}
301
302impl From<String> for Node<str> {
303 fn from(node: String) -> Self {
304 Self::new_str(&node)
305 }
306}
307
308impl From<&'_ Node<str>> for String {
309 fn from(node: &'_ Node<str>) -> Self {
310 node.as_str().to_owned()
311 }
312}
313
314impl From<Node<str>> for String {
315 fn from(node: Node<str>) -> Self {
316 node.as_str().to_owned()
317 }
318}
319
320impl<T: serde::Serialize> serde::Serialize for Node<T> {
321 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
322 where
323 S: serde::Serializer,
324 {
325 T::serialize(self, serializer)
326 }
327}