1use std::{
36 fmt::{Debug, Display, Formatter},
37 iter::FusedIterator,
38};
39
40use crate::{
41 arena::{Entry, Id, Identifiable},
42 lexis::{
43 Length,
44 LineIndex,
45 Site,
46 SiteRef,
47 SourceCode,
48 ToSpan,
49 Token,
50 TokenBuffer,
51 TokenCount,
52 TokenCursor,
53 TokenRef,
54 },
55 syntax::{ErrorRef, Node, NodeRef, SyntaxError, SyntaxTree},
56 units::{CompilationUnit, ImmutableUnit, MutableUnit, VoidWatcher, Watcher},
57};
58
59pub enum Document<N: Node> {
75 Mutable(MutableUnit<N>),
77
78 Immutable(ImmutableUnit<N>),
81}
82
83impl<N: Node> Debug for Document<N> {
84 #[inline(always)]
85 fn fmt(&self, formatter: &mut Formatter) -> std::fmt::Result {
86 match self {
87 Self::Mutable(unit) => Debug::fmt(unit, formatter),
88 Self::Immutable(unit) => Debug::fmt(unit, formatter),
89 }
90 }
91}
92
93impl<N: Node> Display for Document<N> {
94 #[inline(always)]
95 fn fmt(&self, formatter: &mut Formatter) -> std::fmt::Result {
96 match self {
97 Self::Mutable(unit) => Display::fmt(unit, formatter),
98 Self::Immutable(unit) => Display::fmt(unit, formatter),
99 }
100 }
101}
102
103impl<N: Node> Identifiable for Document<N> {
104 #[inline(always)]
105 fn id(&self) -> Id {
106 match self {
107 Self::Mutable(unit) => unit.id(),
108 Self::Immutable(unit) => unit.id(),
109 }
110 }
111}
112
113impl<N: Node> Default for Document<N> {
114 #[inline(always)]
115 fn default() -> Self {
116 Self::Mutable(MutableUnit::default())
117 }
118}
119
120impl<N: Node> From<MutableUnit<N>> for Document<N> {
121 #[inline(always)]
122 fn from(unit: MutableUnit<N>) -> Self {
123 Self::Mutable(unit)
124 }
125}
126
127impl<N: Node> From<ImmutableUnit<N>> for Document<N> {
128 #[inline(always)]
129 fn from(unit: ImmutableUnit<N>) -> Self {
130 Self::Immutable(unit)
131 }
132}
133
134impl<N: Node, S: AsRef<str>> From<S> for Document<N> {
135 #[inline(always)]
136 fn from(string: S) -> Self {
137 Self::Mutable(MutableUnit::from(string))
138 }
139}
140
141impl<N: Node> SourceCode for Document<N> {
142 type Token = N::Token;
143
144 type Cursor<'document> = DocumentCursor<'document, N>;
145
146 type CharIterator<'document> = DocumentCharIter<'document, N>;
147
148 #[inline(always)]
149 fn chars(&self, span: impl ToSpan) -> Self::CharIterator<'_> {
150 match self {
151 Self::Mutable(unit) => DocumentCharIter::Mutable(unit.chars(span)),
152 Self::Immutable(unit) => DocumentCharIter::Immutable(unit.chars(span)),
153 }
154 }
155
156 #[inline(always)]
157 fn has_chunk(&self, entry: &Entry) -> bool {
158 match self {
159 Self::Mutable(unit) => unit.has_chunk(entry),
160 Self::Immutable(unit) => unit.has_chunk(entry),
161 }
162 }
163
164 #[inline(always)]
165 fn get_token(&self, entry: &Entry) -> Option<Self::Token> {
166 match self {
167 Self::Mutable(unit) => unit.get_token(entry),
168 Self::Immutable(unit) => unit.get_token(entry),
169 }
170 }
171
172 #[inline(always)]
173 fn get_site(&self, entry: &Entry) -> Option<Site> {
174 match self {
175 Self::Mutable(unit) => unit.get_site(entry),
176 Self::Immutable(unit) => unit.get_site(entry),
177 }
178 }
179
180 #[inline(always)]
181 fn get_string(&self, entry: &Entry) -> Option<&str> {
182 match self {
183 Self::Mutable(unit) => unit.get_string(entry),
184 Self::Immutable(unit) => unit.get_string(entry),
185 }
186 }
187
188 #[inline(always)]
189 fn get_length(&self, entry: &Entry) -> Option<Length> {
190 match self {
191 Self::Mutable(unit) => unit.get_length(entry),
192 Self::Immutable(unit) => unit.get_length(entry),
193 }
194 }
195
196 #[inline(always)]
197 fn cursor(&self, span: impl ToSpan) -> Self::Cursor<'_> {
198 match self {
199 Self::Mutable(unit) => DocumentCursor::Mutable(unit.cursor(span)),
200 Self::Immutable(unit) => DocumentCursor::Immutable(unit.cursor(span)),
201 }
202 }
203
204 #[inline(always)]
205 fn length(&self) -> Length {
206 match self {
207 Self::Mutable(unit) => unit.length(),
208 Self::Immutable(unit) => unit.length(),
209 }
210 }
211
212 #[inline(always)]
213 fn tokens(&self) -> TokenCount {
214 match self {
215 Self::Mutable(unit) => unit.tokens(),
216 Self::Immutable(unit) => unit.tokens(),
217 }
218 }
219
220 #[inline(always)]
221 fn lines(&self) -> &LineIndex {
222 match self {
223 Self::Mutable(unit) => unit.lines(),
224 Self::Immutable(unit) => unit.lines(),
225 }
226 }
227}
228
229impl<N: Node> SyntaxTree for Document<N> {
230 type Node = N;
231
232 type NodeIterator<'document> = DocumentNodeIter<'document, N>;
233
234 type ErrorIterator<'document> = DocumentErrorIter<'document, N>;
235
236 #[inline(always)]
237 fn root_node_ref(&self) -> NodeRef {
238 match self {
239 Self::Mutable(unit) => unit.root_node_ref(),
240 Self::Immutable(unit) => unit.root_node_ref(),
241 }
242 }
243
244 #[inline(always)]
245 fn node_refs(&self) -> Self::NodeIterator<'_> {
246 match self {
247 Self::Mutable(unit) => DocumentNodeIter::Mutable(unit.node_refs()),
248 Self::Immutable(unit) => DocumentNodeIter::Immutable(unit.node_refs()),
249 }
250 }
251
252 #[inline(always)]
253 fn error_refs(&self) -> Self::ErrorIterator<'_> {
254 match self {
255 Self::Mutable(unit) => DocumentErrorIter::Mutable(unit.error_refs()),
256 Self::Immutable(unit) => DocumentErrorIter::Immutable(unit.error_refs()),
257 }
258 }
259
260 #[inline(always)]
261 fn has_node(&self, entry: &Entry) -> bool {
262 match self {
263 Self::Mutable(unit) => unit.has_node(entry),
264 Self::Immutable(unit) => unit.has_node(entry),
265 }
266 }
267
268 #[inline(always)]
269 fn get_node(&self, entry: &Entry) -> Option<&Self::Node> {
270 match self {
271 Self::Mutable(unit) => unit.get_node(entry),
272 Self::Immutable(unit) => unit.get_node(entry),
273 }
274 }
275
276 #[inline(always)]
277 fn get_node_mut(&mut self, entry: &Entry) -> Option<&mut Self::Node> {
278 match self {
279 Self::Mutable(unit) => unit.get_node_mut(entry),
280 Self::Immutable(unit) => unit.get_node_mut(entry),
281 }
282 }
283
284 #[inline(always)]
285 fn has_error(&self, entry: &Entry) -> bool {
286 match self {
287 Self::Mutable(unit) => unit.has_error(entry),
288 Self::Immutable(unit) => unit.has_error(entry),
289 }
290 }
291
292 #[inline(always)]
293 fn get_error(&self, entry: &Entry) -> Option<&SyntaxError> {
294 match self {
295 Self::Mutable(unit) => unit.get_error(entry),
296 Self::Immutable(unit) => unit.get_error(entry),
297 }
298 }
299}
300
301impl<N: Node> CompilationUnit for Document<N> {
302 #[inline(always)]
303 fn is_mutable(&self) -> bool {
304 match self {
305 Self::Mutable(..) => true,
306 Self::Immutable(..) => false,
307 }
308 }
309
310 #[inline(always)]
311 fn into_token_buffer(self) -> TokenBuffer<N::Token> {
312 match self {
313 Self::Mutable(unit) => unit.into_token_buffer(),
314 Self::Immutable(unit) => unit.into_token_buffer(),
315 }
316 }
317
318 #[inline(always)]
319 fn into_document(self) -> Document<N> {
320 self
321 }
322
323 #[inline(always)]
324 fn into_mutable_unit(self) -> MutableUnit<N> {
325 match self {
326 Self::Mutable(unit) => unit,
327 Self::Immutable(unit) => unit.into_mutable_unit(),
328 }
329 }
330
331 #[inline(always)]
332 fn into_immutable_unit(self) -> ImmutableUnit<N> {
333 match self {
334 Self::Mutable(unit) => unit.into_immutable_unit(),
335 Self::Immutable(unit) => unit,
336 }
337 }
338
339 #[inline(always)]
340 fn cover(&self, span: impl ToSpan) -> NodeRef {
341 match self {
342 Self::Mutable(unit) => unit.cover(span),
343 Self::Immutable(unit) => unit.cover(span),
344 }
345 }
346}
347
348impl<N: Node> Document<N> {
349 #[inline(always)]
355 pub fn new_mutable(text: impl Into<TokenBuffer<N::Token>>) -> Self {
356 Self::Mutable(MutableUnit::new(text))
357 }
358
359 #[inline(always)]
366 pub fn new_immutable(text: impl Into<TokenBuffer<N::Token>>) -> Self {
367 Self::Immutable(ImmutableUnit::new(text))
368 }
369
370 #[inline(always)]
394 pub fn write(&mut self, span: impl ToSpan, text: impl AsRef<str>) {
395 self.write_and_watch(span, text, &mut VoidWatcher)
396 }
397
398 #[inline(always)]
411 pub fn write_and_watch(
412 &mut self,
413 span: impl ToSpan,
414 text: impl AsRef<str>,
415 watcher: &mut impl Watcher,
416 ) {
417 let unit = match self.as_mutable() {
418 Some(unit) => unit,
419 None => panic!("Specified Document is not mutable."),
420 };
421
422 unit.write_and_watch(span, text, watcher);
423 }
424
425 #[inline(always)]
428 pub fn as_mutable(&mut self) -> Option<&mut MutableUnit<N>> {
429 match self {
430 Self::Mutable(unit) => Some(unit),
431 Self::Immutable(..) => None,
432 }
433 }
434
435 #[inline(always)]
445 pub fn into_mutable(self) -> Self {
446 match self {
447 Self::Mutable(..) => self,
448 Self::Immutable(unit) => Self::Mutable(unit.into_mutable_unit()),
449 }
450 }
451
452 #[inline(always)]
462 pub fn into_immutable(self) -> Self {
463 match self {
464 Self::Mutable(unit) => Self::Immutable(unit.into_immutable_unit()),
465 Self::Immutable(..) => self,
466 }
467 }
468}
469
470impl<T: Token> TokenBuffer<T> {
471 #[inline(always)]
476 pub fn into_document<N>(self) -> Document<N>
477 where
478 N: Node<Token = T>,
479 {
480 self.into_mutable_unit().into()
481 }
482}
483
484pub enum DocumentCursor<'document, N: Node> {
485 Mutable(<MutableUnit<N> as SourceCode>::Cursor<'document>),
486 Immutable(<ImmutableUnit<N> as SourceCode>::Cursor<'document>),
487}
488
489impl<'document, N: Node> Identifiable for DocumentCursor<'document, N> {
490 #[inline(always)]
491 fn id(&self) -> Id {
492 match self {
493 Self::Mutable(cursor) => cursor.id(),
494 Self::Immutable(cursor) => cursor.id(),
495 }
496 }
497}
498
499impl<'document, N: Node> TokenCursor<'document> for DocumentCursor<'document, N> {
500 type Token = N::Token;
501
502 #[inline(always)]
503 fn advance(&mut self) -> bool {
504 match self {
505 Self::Mutable(cursor) => cursor.advance(),
506 Self::Immutable(cursor) => cursor.advance(),
507 }
508 }
509
510 #[inline(always)]
511 fn skip(&mut self, distance: TokenCount) {
512 match self {
513 Self::Mutable(cursor) => cursor.skip(distance),
514 Self::Immutable(cursor) => cursor.skip(distance),
515 }
516 }
517
518 #[inline(always)]
519 fn token(&mut self, distance: TokenCount) -> Self::Token {
520 match self {
521 Self::Mutable(cursor) => cursor.token(distance),
522 Self::Immutable(cursor) => cursor.token(distance),
523 }
524 }
525
526 #[inline(always)]
527 fn site(&mut self, distance: TokenCount) -> Option<Site> {
528 match self {
529 Self::Mutable(cursor) => cursor.site(distance),
530 Self::Immutable(cursor) => cursor.site(distance),
531 }
532 }
533
534 #[inline(always)]
535 fn length(&mut self, distance: TokenCount) -> Option<Length> {
536 match self {
537 Self::Mutable(cursor) => cursor.length(distance),
538 Self::Immutable(cursor) => cursor.length(distance),
539 }
540 }
541
542 #[inline(always)]
543 fn string(&mut self, distance: TokenCount) -> Option<&'document str> {
544 match self {
545 Self::Mutable(cursor) => cursor.string(distance),
546 Self::Immutable(cursor) => cursor.string(distance),
547 }
548 }
549
550 #[inline(always)]
551 fn token_ref(&mut self, distance: TokenCount) -> TokenRef {
552 match self {
553 Self::Mutable(cursor) => cursor.token_ref(distance),
554 Self::Immutable(cursor) => cursor.token_ref(distance),
555 }
556 }
557
558 #[inline(always)]
559 fn site_ref(&mut self, distance: TokenCount) -> SiteRef {
560 match self {
561 Self::Mutable(cursor) => cursor.site_ref(distance),
562 Self::Immutable(cursor) => cursor.site_ref(distance),
563 }
564 }
565
566 #[inline(always)]
567 fn end_site_ref(&mut self) -> SiteRef {
568 match self {
569 Self::Mutable(cursor) => cursor.end_site_ref(),
570 Self::Immutable(cursor) => cursor.end_site_ref(),
571 }
572 }
573}
574
575pub enum DocumentCharIter<'document, N: Node> {
576 Mutable(<MutableUnit<N> as SourceCode>::CharIterator<'document>),
577 Immutable(<ImmutableUnit<N> as SourceCode>::CharIterator<'document>),
578}
579
580impl<'document, N: Node> Iterator for DocumentCharIter<'document, N> {
581 type Item = char;
582
583 #[inline(always)]
584 fn next(&mut self) -> Option<Self::Item> {
585 match self {
586 Self::Mutable(iterator) => iterator.next(),
587 Self::Immutable(iterator) => iterator.next(),
588 }
589 }
590}
591
592impl<'document, N: Node> FusedIterator for DocumentCharIter<'document, N> {}
593
594pub enum DocumentNodeIter<'document, N: Node> {
595 Mutable(<MutableUnit<N> as SyntaxTree>::NodeIterator<'document>),
596 Immutable(<ImmutableUnit<N> as SyntaxTree>::NodeIterator<'document>),
597}
598
599impl<'document, N: Node> Iterator for DocumentNodeIter<'document, N> {
600 type Item = NodeRef;
601
602 #[inline(always)]
603 fn next(&mut self) -> Option<Self::Item> {
604 match self {
605 Self::Mutable(iterator) => iterator.next(),
606 Self::Immutable(iterator) => iterator.next(),
607 }
608 }
609}
610
611impl<'document, N: Node> FusedIterator for DocumentNodeIter<'document, N> {}
612
613pub enum DocumentErrorIter<'document, N: Node> {
614 Mutable(<MutableUnit<N> as SyntaxTree>::ErrorIterator<'document>),
615 Immutable(<ImmutableUnit<N> as SyntaxTree>::ErrorIterator<'document>),
616}
617
618impl<'document, N: Node> Iterator for DocumentErrorIter<'document, N> {
619 type Item = ErrorRef;
620
621 #[inline(always)]
622 fn next(&mut self) -> Option<Self::Item> {
623 match self {
624 Self::Mutable(iterator) => iterator.next(),
625 Self::Immutable(iterator) => iterator.next(),
626 }
627 }
628}
629
630impl<'document, N: Node> FusedIterator for DocumentErrorIter<'document, N> {}