Skip to main content

noyalib/cst/
syntax.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2// Copyright (c) 2026 Noyalib. All rights reserved.
3
4//! Syntax-kind tags for green-tree nodes and tokens.
5//!
6//! Mirrors the design doc's enumeration. Token (leaf) kinds are
7//! ordered before composite (non-leaf) kinds in the variant list to
8//! make the leaf-vs-composite distinction visible at a glance.
9
10/// Kind of a green-tree node or token.
11///
12/// Token kinds describe leaves whose `text` slice is the source
13/// substring they came from. Composite kinds describe parent nodes
14/// whose `text` is the concatenation of their descendants.
15///
16/// # Examples
17///
18/// ```
19/// use noyalib::cst::SyntaxKind;
20/// assert!(SyntaxKind::PlainScalar.is_token());
21/// assert!(!SyntaxKind::Document.is_token());
22/// ```
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
24#[non_exhaustive]
25pub enum SyntaxKind {
26    // ── trivia (leaves) ─────────────────────────────────────────
27    /// Run of inline blanks (spaces and tabs) between tokens.
28    Whitespace,
29    /// A single line break (`\n` or `\r\n`).
30    Newline,
31    /// A `# …` comment up to the next line break.
32    Comment,
33    /// A UTF-8 byte-order mark consumed at stream start.
34    Bom,
35    /// A `%YAML` / `%TAG` / reserved directive line, *including* the
36    /// leading `%` and excluding the terminating line break.
37    Directive,
38
39    // ── structural punctuation (leaves) ─────────────────────────
40    /// `-` block-sequence indicator.
41    DashIndicator,
42    /// `?` explicit-key indicator.
43    QuestionIndicator,
44    /// `:` value indicator.
45    ColonIndicator,
46    /// `,` flow-entry indicator.
47    Comma,
48    /// `[` flow-sequence open.
49    OpenBracket,
50    /// `]` flow-sequence close.
51    CloseBracket,
52    /// `{` flow-mapping open.
53    OpenBrace,
54    /// `}` flow-mapping close.
55    CloseBrace,
56    /// `&name` anchor mark — leaf includes the `&`.
57    AnchorMark,
58    /// `*name` alias mark — leaf includes the `*`.
59    AliasMark,
60    /// `!tag` tag mark — leaf includes the `!` and any handle / suffix.
61    TagMark,
62    /// `---` document-start indicator.
63    DocStart,
64    /// `...` document-end indicator.
65    DocEnd,
66
67    // ── scalar leaves ───────────────────────────────────────────
68    /// A plain (unquoted) scalar.
69    PlainScalar,
70    /// A `'…'` single-quoted scalar.
71    SingleQuotedScalar,
72    /// A `"…"` double-quoted scalar.
73    DoubleQuotedScalar,
74    /// A `|…` literal block scalar (header + content).
75    LiteralScalar,
76    /// A `>…` folded block scalar (header + content).
77    FoldedScalar,
78
79    // ── composite (non-leaf) kinds ──────────────────────────────
80    /// The whole stream — root of the green tree returned by
81    /// [`crate::cst::parse_document`] and [`crate::cst::parse_stream`].
82    Stream,
83    /// A single YAML document inside the stream.
84    Document,
85    /// A block-style mapping. Children are [`Self::MappingEntry`]
86    /// nodes (or trivia) in source order.
87    BlockMapping,
88    /// A block-style sequence. Children are [`Self::SequenceItem`]
89    /// nodes (or trivia) in source order.
90    BlockSequence,
91    /// A `{ … }` flow mapping. Children are the brace tokens, the
92    /// entries' tokens, and inter-token trivia. Flow content is
93    /// kept flat — flow entries are not subdivided into
94    /// [`Self::MappingEntry`] composites.
95    FlowMapping,
96    /// A `[ … ]` flow sequence. Flow content is kept flat — see
97    /// [`Self::FlowMapping`].
98    FlowSequence,
99    /// A single key/value entry of a [`Self::BlockMapping`]. Holds
100    /// the (optional) `?` indicator, the key tokens, the `:`
101    /// indicator, the value tokens (which may themselves be a nested
102    /// block / flow collection), and any inline trailing trivia.
103    MappingEntry,
104    /// A single item of a [`Self::BlockSequence`], including the `-`
105    /// indicator and the value tokens (or a nested collection).
106    SequenceItem,
107}
108
109impl SyntaxKind {
110    /// `true` for leaves whose `text` is a verbatim source slice;
111    /// `false` for composite parent nodes.
112    ///
113    /// # Examples
114    ///
115    /// ```
116    /// use noyalib::cst::SyntaxKind;
117    /// assert!(SyntaxKind::Whitespace.is_token());
118    /// assert!(!SyntaxKind::Stream.is_token());
119    /// assert!(!SyntaxKind::BlockMapping.is_token());
120    /// ```
121    #[must_use]
122    pub const fn is_token(self) -> bool {
123        !matches!(
124            self,
125            Self::Stream
126                | Self::Document
127                | Self::BlockMapping
128                | Self::BlockSequence
129                | Self::FlowMapping
130                | Self::FlowSequence
131                | Self::MappingEntry
132                | Self::SequenceItem
133        )
134    }
135}