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