apollo_compiler/schema/
component.rs1use crate::parser::SourceSpan;
2use crate::Name;
3use crate::Node;
4use std::fmt;
5use std::hash;
6use std::ops::Deref;
7use std::ops::DerefMut;
8use triomphe::Arc;
9
10#[derive(Debug, Clone)]
19pub struct Component<T: ?Sized> {
20 pub origin: ComponentOrigin,
21 pub node: Node<T>,
22}
23
24#[derive(Debug, Clone, Hash, PartialEq, Eq)]
27pub enum ComponentOrigin {
28 Definition,
29 Extension(ExtensionId),
30}
31
32#[derive(Debug, Clone, Eq)]
37pub struct ExtensionId {
38 arc: Arc<Option<SourceSpan>>,
39}
40
41impl ExtensionId {
42 pub fn new<T>(extension: &Node<T>) -> Self {
43 Self {
44 arc: 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 Arc::ptr_eq(&self.arc, &other.arc)
62 }
63}
64
65impl hash::Hash for ExtensionId {
66 fn hash<H: hash::Hasher>(&self, state: &mut H) {
67 Arc::as_ptr(&self.arc).hash(state);
68 }
69}
70
71impl ComponentOrigin {
72 pub fn extension_id(&self) -> Option<&ExtensionId> {
73 match self {
74 ComponentOrigin::Definition => None,
75 ComponentOrigin::Extension(id) => Some(id),
76 }
77 }
78}
79
80impl<T> Component<T> {
81 pub fn new(node: T) -> Self {
83 Self {
84 origin: ComponentOrigin::Definition,
85 node: Node::new(node),
86 }
87 }
88}
89
90impl<T: ?Sized + hash::Hash> hash::Hash for Component<T> {
91 fn hash<H: hash::Hasher>(&self, state: &mut H) {
92 self.node.hash(state); }
94}
95
96impl<T: ?Sized + Eq> Eq for Component<T> {}
97
98impl<T: ?Sized + PartialEq> PartialEq for Component<T> {
99 fn eq(&self, other: &Self) -> bool {
100 self.node == other.node }
102}
103
104impl<T: ?Sized> Deref for Component<T> {
105 type Target = Node<T>;
106
107 fn deref(&self) -> &Self::Target {
108 &self.node
109 }
110}
111
112impl<T: ?Sized> DerefMut for Component<T> {
113 fn deref_mut(&mut self) -> &mut Self::Target {
114 &mut self.node
115 }
116}
117
118impl<T: ?Sized> AsRef<T> for Component<T> {
119 fn as_ref(&self) -> &T {
120 &self.node
121 }
122}
123
124impl<T> From<T> for Component<T> {
125 fn from(node: T) -> Self {
126 Component::new(node)
127 }
128}
129
130impl<T> From<Node<T>> for Component<T> {
131 fn from(node: Node<T>) -> Self {
132 Self {
133 origin: ComponentOrigin::Definition,
134 node,
135 }
136 }
137}
138
139#[derive(Debug, Clone)]
149pub struct ComponentName {
150 pub origin: ComponentOrigin,
151 pub name: Name,
152}
153
154impl From<&Name> for ComponentName {
155 fn from(value: &Name) -> Self {
156 value.to_component(ComponentOrigin::Definition)
157 }
158}
159
160impl From<Name> for ComponentName {
161 fn from(value: Name) -> Self {
162 value.to_component(ComponentOrigin::Definition)
163 }
164}
165
166impl hash::Hash for ComponentName {
167 fn hash<H: hash::Hasher>(&self, state: &mut H) {
168 self.name.hash(state); }
170}
171
172impl Eq for ComponentName {}
173
174impl PartialEq for ComponentName {
175 fn eq(&self, other: &Self) -> bool {
176 self.name == other.name }
178}
179
180impl PartialEq<str> for ComponentName {
181 fn eq(&self, other: &str) -> bool {
182 self.as_str() == other
183 }
184}
185impl PartialEq<Name> for ComponentName {
186 fn eq(&self, other: &Name) -> bool {
187 self.name == *other
188 }
189}
190
191impl Deref for ComponentName {
192 type Target = Name;
193
194 #[inline]
195 fn deref(&self) -> &Self::Target {
196 &self.name
197 }
198}
199
200impl std::borrow::Borrow<Name> for ComponentName {
201 fn borrow(&self) -> &Name {
202 self
203 }
204}
205
206impl std::borrow::Borrow<str> for ComponentName {
207 fn borrow(&self) -> &str {
208 self
209 }
210}
211
212impl AsRef<str> for ComponentName {
213 fn as_ref(&self) -> &str {
214 self
215 }
216}
217
218impl fmt::Display for ComponentName {
219 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
220 self.name.fmt(f)
221 }
222}