1use crate::parser::FileId;
2use crate::parser::LineColumn;
3use crate::parser::SourceMap;
4use crate::parser::SourceSpan;
5use crate::schema::Component;
6use crate::schema::ComponentOrigin;
7use std::fmt;
8use std::hash::Hash;
9use std::hash::Hasher;
10use std::ops::Range;
11use triomphe::HeaderSlice;
12
13#[derive(serde::Deserialize)]
21#[serde(from = "T")]
22pub struct Node<T: ?Sized>(triomphe::Arc<HeaderSlice<Header, T>>);
23
24#[derive(Clone)]
25struct Header {
26 location: Option<SourceSpan>,
27}
28
29impl<T> Node<T> {
30 #[inline]
32 pub fn new_parsed(node: T, location: SourceSpan) -> Self {
33 Self::new_opt_location(node, Some(location))
34 }
35
36 pub fn new(node: T) -> Self {
38 Self::new_opt_location(node, None)
39 }
40
41 pub(crate) fn new_opt_location(node: T, location: Option<SourceSpan>) -> Self {
42 Self(triomphe::Arc::new(HeaderSlice {
43 header: Header { location },
44 slice: node,
45 }))
46 }
47}
48
49impl Node<str> {
50 #[inline]
52 pub fn new_str_parsed(node: &str, location: SourceSpan) -> Self {
53 Self::new_str_opt_location(node, Some(location))
54 }
55
56 pub fn new_str(node: &str) -> Self {
58 Self::new_str_opt_location(node, None)
59 }
60
61 pub(crate) fn new_str_opt_location(node: &str, location: Option<SourceSpan>) -> Self {
62 Self(triomphe::Arc::from_header_and_str(
63 Header { location },
64 node,
65 ))
66 }
67
68 pub fn as_str(&self) -> &str {
69 self
70 }
71}
72
73impl<T: ?Sized> Node<T> {
74 pub fn location(&self) -> Option<SourceSpan> {
77 self.0.header.location
78 }
79
80 pub fn is_built_in(&self) -> bool {
83 self.location().map(|l| l.file_id()) == Some(FileId::BUILT_IN)
84 }
85
86 pub fn line_column_range(&self, sources: &SourceMap) -> Option<Range<LineColumn>> {
88 self.location()?.line_column_range(sources)
89 }
90
91 pub fn same_location<U>(&self, node: U) -> Node<U> {
93 Node::new_opt_location(node, self.0.header.location)
94 }
95
96 pub fn to_component(&self, origin: ComponentOrigin) -> Component<T> {
97 Component {
98 origin,
99 node: self.clone(),
100 }
101 }
102
103 pub fn ptr_eq(&self, other: &Self) -> bool {
107 triomphe::Arc::ptr_eq(&self.0, &other.0)
108 }
109
110 pub fn make_mut(&mut self) -> &mut T
124 where
125 T: Clone,
126 {
127 let inner = triomphe::Arc::make_mut(&mut self.0);
128 &mut inner.slice
131 }
132
133 pub fn get_mut(&mut self) -> Option<&mut T> {
135 triomphe::Arc::get_mut(&mut self.0).map(|inner| &mut inner.slice)
136 }
137}
138
139impl<T: ?Sized> std::ops::Deref for Node<T> {
140 type Target = T;
141
142 fn deref(&self) -> &Self::Target {
143 &self.0.slice
144 }
145}
146
147impl<T: ?Sized> Clone for Node<T> {
148 fn clone(&self) -> Self {
149 Self(self.0.clone())
150 }
151}
152
153impl<T: Default> Default for Node<T> {
154 fn default() -> Self {
155 Self::new(T::default())
156 }
157}
158
159impl<T: ?Sized + fmt::Debug> fmt::Debug for Node<T> {
160 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161 if let Some(location) = self.location() {
162 write!(f, "{location:?} ")?
163 }
164 self.0.slice.fmt(f)
165 }
166}
167
168impl<T: ?Sized + fmt::Display> fmt::Display for Node<T> {
169 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170 T::fmt(self, f)
171 }
172}
173
174impl<T: ?Sized + Eq> Eq for Node<T> {}
175
176impl<T: ?Sized + PartialEq> PartialEq for Node<T> {
177 fn eq(&self, other: &Self) -> bool {
178 self.ptr_eq(other) || self.0.slice == other.0.slice }
181}
182
183impl<T: ?Sized + Hash> Hash for Node<T> {
184 fn hash<H: Hasher>(&self, state: &mut H) {
185 self.0.slice.hash(state)
186 }
187}
188
189impl<T: ?Sized> std::borrow::Borrow<T> for Node<T> {
190 fn borrow(&self) -> &T {
191 self
192 }
193}
194
195impl<T: ?Sized> AsRef<T> for Node<T> {
196 fn as_ref(&self) -> &T {
197 self
198 }
199}
200
201impl<T> From<T> for Node<T> {
202 fn from(node: T) -> Self {
203 Self::new(node)
204 }
205}
206
207impl From<&'_ str> for Node<str> {
208 fn from(node: &'_ str) -> Self {
209 Self::new_str(node)
210 }
211}
212
213impl From<&'_ String> for Node<str> {
214 fn from(node: &'_ String) -> Self {
215 Self::new_str(node)
216 }
217}
218
219impl From<String> for Node<str> {
220 fn from(node: String) -> Self {
221 Self::new_str(&node)
222 }
223}
224
225impl From<&'_ Node<str>> for String {
226 fn from(node: &'_ Node<str>) -> Self {
227 node.as_str().to_owned()
228 }
229}
230
231impl From<Node<str>> for String {
232 fn from(node: Node<str>) -> Self {
233 node.as_str().to_owned()
234 }
235}
236
237impl<T: serde::Serialize> serde::Serialize for Node<T> {
238 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
239 where
240 S: serde::Serializer,
241 {
242 T::serialize(self, serializer)
243 }
244}