type_sitter_lib/node/
wrappers.rs1use crate::raw;
2use crate::{IncorrectKind, Node, NodeResult};
3use std::fmt::Debug;
4
5macro_rules! define_simple_wrapper {
6 ($comment:literal, $Type:ident, $method:ident, $name:literal) => {
7 #[doc = $comment]
8 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9 #[repr(transparent)]
10 pub struct $Type<'tree>(raw::Node<'tree>);
11
12 impl<'tree> Node<'tree> for $Type<'tree> {
13 type WithLifetime<'a> = $Type<'a>;
14
15 const KIND: &'static str = concat!("{", $name, "}");
16
17 fn try_from_raw(node: raw::Node<'tree>) -> NodeResult<'tree, Self> {
18 if node.$method() {
19 Ok($Type(node))
20 } else {
21 Err(IncorrectKind::new::<Self>(node))
22 }
23 }
24
25 #[inline]
26 unsafe fn from_raw_unchecked(node: raw::Node<'tree>) -> Self {
27 debug_assert!(node.$method());
28 $Type(node)
29 }
30
31 #[inline]
32 fn raw(&self) -> &raw::Node<'tree> {
33 &self.0
34 }
35
36 #[inline]
37 fn raw_mut(&mut self) -> &mut raw::Node<'tree> {
38 &mut self.0
39 }
40
41 #[inline]
42 fn into_raw(self) -> raw::Node<'tree> {
43 self.0
44 }
45 }
46 };
47}
48
49define_simple_wrapper! {
50 "A node that can annotate any other node, e.g. a comment.",
51 Extra,
52 is_extra,
53 "extra"
54}
55
56define_simple_wrapper! {
57 "A stub node that indicates a localized parse error.",
58 Error,
59 is_error,
60 "error"
61}
62
63define_simple_wrapper! {
64 "A stub node that indicates another node was expected.",
65 Missing,
66 is_missing,
67 "missing"
68}
69
70define_simple_wrapper! {
71 "A node that is untyped other than being named.",
72 UntypedNamedNode,
73 is_named,
74 "untyped named"
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
82#[repr(transparent)]
83pub struct UntypedNode<'tree>(raw::Node<'tree>);
84
85impl<'tree> UntypedNode<'tree> {
86 #[inline]
89 pub fn new(node: raw::Node<'tree>) -> Self {
90 Self(node)
91 }
92
93 #[inline]
97 pub fn r#ref<'a>(node: &'a raw::Node<'tree>) -> &'a Self {
98 unsafe { &*(node as *const raw::Node<'tree> as *const Self) }
99 }
100
101 #[inline]
105 pub fn r#mut<'a>(node: &'a mut raw::Node<'tree>) -> &'a mut Self {
106 unsafe { &mut *(node as *mut raw::Node<'tree> as *mut Self) }
107 }
108
109 #[inline]
111 pub fn is_error(&self) -> bool {
112 self.raw().is_error()
113 }
114
115 #[inline]
117 pub fn is_missing(&self) -> bool {
118 self.raw().is_missing()
119 }
120
121 #[inline]
123 pub fn is_extra(&self) -> bool {
124 self.raw().is_extra()
125 }
126
127 #[inline]
131 pub fn downcast<Type: Node<'tree>>(&self) -> NodeResult<'_, Type> {
132 Type::try_from_raw(self.0)
133 }
134}
135
136impl<'tree> From<raw::Node<'tree>> for UntypedNode<'tree> {
137 fn from(value: raw::Node<'tree>) -> Self {
138 Self(value)
139 }
140}
141
142impl<'tree> Node<'tree> for UntypedNode<'tree> {
143 type WithLifetime<'a> = UntypedNode<'a>;
144
145 const KIND: &'static str = "{untyped}";
146
147 fn try_from_raw(node: raw::Node<'tree>) -> NodeResult<'tree, Self> {
148 Ok(UntypedNode(node))
149 }
150
151 #[inline]
152 unsafe fn from_raw_unchecked(node: raw::Node<'tree>) -> Self {
153 UntypedNode(node)
154 }
155
156 #[inline]
157 fn raw(&self) -> &raw::Node<'tree> {
158 &self.0
159 }
160
161 #[inline]
162 fn raw_mut(&mut self) -> &mut raw::Node<'tree> {
163 &mut self.0
164 }
165
166 #[inline]
167 fn into_raw(self) -> raw::Node<'tree> {
168 self.0
169 }
170}
171
172impl<'tree> UntypedNamedNode<'tree> {
173 #[inline]
177 pub fn downcast<Type: Node<'tree>>(&self) -> NodeResult<'_, Type> {
178 Type::try_from_raw(self.0)
179 }
180}