Skip to main content

rlsp_yaml_parser/
node.rs

1// SPDX-License-Identifier: MIT
2
3//! YAML AST node types.
4//!
5//! [`Node<Loc>`] is the core type — a YAML value parameterized by its
6//! location type.  For most uses `Loc = Span`.  The loader produces
7//! `Vec<Document<Span>>`.
8
9use crate::event::ScalarStyle;
10use crate::pos::Span;
11
12// ---------------------------------------------------------------------------
13// Public types
14// ---------------------------------------------------------------------------
15
16/// A YAML document: a root node plus directive metadata.
17#[derive(Debug, Clone, PartialEq)]
18pub struct Document<Loc = Span> {
19    /// The root node of the document.
20    pub root: Node<Loc>,
21    /// YAML version from `%YAML` directive, if present.
22    pub version: Option<(u8, u8)>,
23    /// Tag handle/prefix pairs from `%TAG` directives.
24    pub tags: Vec<(String, String)>,
25    /// Comments that appear at document level (before or between nodes).
26    pub comments: Vec<String>,
27}
28
29/// A YAML node parameterized by its location type.
30#[derive(Debug, Clone, PartialEq)]
31pub enum Node<Loc = Span> {
32    /// A scalar value.
33    Scalar {
34        value: String,
35        style: ScalarStyle,
36        anchor: Option<String>,
37        tag: Option<String>,
38        loc: Loc,
39    },
40    /// A mapping (sequence of key–value pairs preserving declaration order).
41    Mapping {
42        entries: Vec<(Self, Self)>,
43        anchor: Option<String>,
44        tag: Option<String>,
45        loc: Loc,
46    },
47    /// A sequence (ordered list of nodes).
48    Sequence {
49        items: Vec<Self>,
50        anchor: Option<String>,
51        tag: Option<String>,
52        loc: Loc,
53    },
54    /// An alias reference (lossless mode only — resolved mode expands these).
55    Alias { name: String, loc: Loc },
56}
57
58impl<Loc> Node<Loc> {
59    /// Returns the anchor name if this node defines one.
60    pub fn anchor(&self) -> Option<&str> {
61        match self {
62            Self::Scalar { anchor, .. }
63            | Self::Mapping { anchor, .. }
64            | Self::Sequence { anchor, .. } => anchor.as_deref(),
65            Self::Alias { .. } => None,
66        }
67    }
68}