mago_syntax/cst/
trivia.rs1use strum::Display;
2
3use mago_allocator::CopyInto;
4use mago_span::HasSpan;
5use mago_span::Span;
6
7use crate::cst::Sequence;
8
9#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, Display)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize))]
12#[cfg_attr(feature = "serde", serde(tag = "type", content = "value"))]
13pub enum TriviaKind {
14 WhiteSpace,
15 SingleLineComment,
16 MultiLineComment,
17 HashComment,
18 DocBlockComment,
19}
20
21#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize))]
27pub struct Trivia<'arena> {
28 pub kind: TriviaKind,
29 pub span: Span,
30 pub value: &'arena [u8],
31}
32
33impl TriviaKind {
34 #[inline]
36 #[must_use]
37 pub const fn is_comment(&self) -> bool {
38 matches!(
39 self,
40 TriviaKind::SingleLineComment
41 | TriviaKind::MultiLineComment
42 | TriviaKind::HashComment
43 | TriviaKind::DocBlockComment
44 )
45 }
46
47 #[inline]
48 #[must_use]
49 pub const fn is_docblock(&self) -> bool {
50 matches!(self, TriviaKind::DocBlockComment)
51 }
52
53 #[inline]
54 #[must_use]
55 pub const fn is_block_comment(&self) -> bool {
56 matches!(self, TriviaKind::MultiLineComment | TriviaKind::DocBlockComment)
57 }
58
59 #[inline]
60 #[must_use]
61 pub const fn is_single_line_comment(&self) -> bool {
62 matches!(self, TriviaKind::HashComment | TriviaKind::SingleLineComment)
63 }
64}
65
66impl HasSpan for Trivia<'_> {
67 fn span(&self) -> Span {
68 self.span
69 }
70}
71
72pub trait TriviaSequenceExt<'arena> {
77 fn comments<'borrow>(&'borrow self) -> impl Iterator<Item = &'borrow Trivia<'arena>>
78 where
79 'arena: 'borrow;
80}
81
82impl<'arena> TriviaSequenceExt<'arena> for Sequence<'arena, Trivia<'arena>> {
83 #[inline]
84 fn comments<'borrow>(&'borrow self) -> impl Iterator<Item = &'borrow Trivia<'arena>>
85 where
86 'arena: 'borrow,
87 {
88 self.iter().filter(|trivia| trivia.kind.is_comment())
89 }
90}
91
92impl CopyInto for Trivia<'_> {
93 type Output<'arena> = Trivia<'arena>;
94
95 fn copy_into<'arena, A>(&self, arena: &'arena A) -> Self::Output<'arena>
96 where
97 A: mago_allocator::Arena,
98 {
99 Trivia { kind: self.kind, span: self.span, value: arena.alloc_slice_copy(self.value) }
100 }
101}