satteri_plugin_api/
typed_nodes.rs1use satteri_arena::{Arena, ArenaNode};
2use satteri_ast::mdast::codec::*;
3use satteri_ast::mdast::MdastNodeType;
4
5#[derive(Debug, Clone, Copy)]
7pub struct NodePosition {
8 pub start_offset: u32,
9 pub end_offset: u32,
10 pub start_line: u32,
11 pub start_column: u32,
12 pub end_line: u32,
13 pub end_column: u32,
14}
15
16impl NodePosition {
17 pub fn from_node(node: &ArenaNode) -> Self {
18 Self {
19 start_offset: node.start_offset,
20 end_offset: node.end_offset,
21 start_line: node.start_line,
22 start_column: node.start_column,
23 end_line: node.end_line,
24 end_column: node.end_column,
25 }
26 }
27}
28
29pub struct Heading<'a> {
31 pub(crate) node_id: u32,
32 pub(crate) arena: &'a Arena,
33}
34
35impl<'a> Heading<'a> {
36 pub fn id(&self) -> u32 {
37 self.node_id
38 }
39
40 pub fn depth(&self) -> u8 {
41 let data = self.arena.get_type_data(self.node_id);
42 decode_heading_data(data).depth
43 }
44
45 pub fn children(&self) -> &[u32] {
46 self.arena.get_children(self.node_id)
47 }
48
49 pub fn position(&self) -> NodePosition {
50 NodePosition::from_node(self.arena.get_node(self.node_id))
51 }
52}
53
54pub struct Text<'a> {
56 pub(crate) node_id: u32,
57 pub(crate) arena: &'a Arena,
58}
59
60impl<'a> Text<'a> {
61 pub fn id(&self) -> u32 {
62 self.node_id
63 }
64
65 pub fn value(&self) -> &str {
66 let data = self.arena.get_type_data(self.node_id);
67 let string_ref = decode_string_ref_data(data);
68 self.arena.get_str(string_ref)
69 }
70
71 pub fn position(&self) -> NodePosition {
72 NodePosition::from_node(self.arena.get_node(self.node_id))
73 }
74}
75
76pub struct Link<'a> {
78 pub(crate) node_id: u32,
79 pub(crate) arena: &'a Arena,
80}
81
82impl<'a> Link<'a> {
83 pub fn id(&self) -> u32 {
84 self.node_id
85 }
86
87 pub fn url(&self) -> &str {
88 let data = self.arena.get_type_data(self.node_id);
89 let link = decode_link_data(data);
90 self.arena.get_str(link.url)
91 }
92
93 pub fn title(&self) -> Option<&str> {
94 let data = self.arena.get_type_data(self.node_id);
95 let link = decode_link_data(data);
96 if link.title.len > 0 {
97 Some(self.arena.get_str(link.title))
98 } else {
99 None
100 }
101 }
102
103 pub fn children(&self) -> &[u32] {
104 self.arena.get_children(self.node_id)
105 }
106
107 pub fn position(&self) -> NodePosition {
108 NodePosition::from_node(self.arena.get_node(self.node_id))
109 }
110}
111
112pub struct Paragraph<'a> {
114 pub(crate) node_id: u32,
115 pub(crate) arena: &'a Arena,
116}
117
118impl<'a> Paragraph<'a> {
119 pub fn id(&self) -> u32 {
120 self.node_id
121 }
122 pub fn children(&self) -> &[u32] {
123 self.arena.get_children(self.node_id)
124 }
125 pub fn position(&self) -> NodePosition {
126 NodePosition::from_node(self.arena.get_node(self.node_id))
127 }
128}
129
130pub struct Image<'a> {
132 pub(crate) node_id: u32,
133 pub(crate) arena: &'a Arena,
134}
135
136impl<'a> Image<'a> {
137 pub fn id(&self) -> u32 {
138 self.node_id
139 }
140
141 pub fn url(&self) -> &str {
142 let data = self.arena.get_type_data(self.node_id);
143 let img = decode_image_data(data);
144 self.arena.get_str(img.url)
145 }
146
147 pub fn alt(&self) -> &str {
148 let data = self.arena.get_type_data(self.node_id);
149 let img = decode_image_data(data);
150 self.arena.get_str(img.alt)
151 }
152
153 pub fn title(&self) -> Option<&str> {
154 let data = self.arena.get_type_data(self.node_id);
155 let img = decode_image_data(data);
156 if img.title.len > 0 {
157 Some(self.arena.get_str(img.title))
158 } else {
159 None
160 }
161 }
162
163 pub fn position(&self) -> NodePosition {
164 NodePosition::from_node(self.arena.get_node(self.node_id))
165 }
166}
167
168pub struct Code<'a> {
170 pub(crate) node_id: u32,
171 pub(crate) arena: &'a Arena,
172}
173
174impl<'a> Code<'a> {
175 pub fn id(&self) -> u32 {
176 self.node_id
177 }
178
179 pub fn lang(&self) -> Option<&str> {
180 let data = self.arena.get_type_data(self.node_id);
181 let code = decode_code_data(data);
182 if code.lang.len > 0 {
183 Some(self.arena.get_str(code.lang))
184 } else {
185 None
186 }
187 }
188
189 pub fn meta(&self) -> Option<&str> {
190 let data = self.arena.get_type_data(self.node_id);
191 let code = decode_code_data(data);
192 if code.meta.len > 0 {
193 Some(self.arena.get_str(code.meta))
194 } else {
195 None
196 }
197 }
198
199 pub fn value(&self) -> &str {
206 let children = self.arena.get_children(self.node_id);
209 if let Some(&child_id) = children.first() {
210 let child_node = self.arena.get_node(child_id);
211 if child_node.node_type == MdastNodeType::Text as u8 {
212 let data = self.arena.get_type_data(child_id);
213 if !data.is_empty() {
214 let string_ref = decode_string_ref_data(data);
215 return self.arena.get_str(string_ref);
216 }
217 }
218 }
219 ""
221 }
222
223 pub fn position(&self) -> NodePosition {
224 NodePosition::from_node(self.arena.get_node(self.node_id))
225 }
226}