Skip to main content

tsz_parser/parser/
base.rs

1//! Shared parser base types used by both Node and (legacy) AST.
2//!
3//! These types are part of the "thin pipeline" surface area and should remain
4//! available even if the legacy fat AST is disabled.
5
6use serde::{Deserialize, Serialize};
7use wasm_bindgen::prelude::wasm_bindgen;
8
9/// A text range with start and end positions.
10/// All positions are character indices (not byte indices).
11#[wasm_bindgen]
12#[derive(Clone, Copy, Debug, Default, Serialize)]
13pub struct TextRange {
14    pub pos: u32,
15    pub end: u32,
16}
17
18impl<'de> serde::Deserialize<'de> for TextRange {
19    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
20    where
21        D: serde::Deserializer<'de>,
22    {
23        #[derive(serde::Deserialize)]
24        struct Helper {
25            pos: u32,
26            end: u32,
27        }
28
29        let helper = Helper::deserialize(deserializer)?;
30        Ok(Self {
31            pos: helper.pos,
32            end: helper.end,
33        })
34    }
35}
36
37#[cfg(not(target_arch = "wasm32"))]
38impl TextRange {
39    #[must_use]
40    pub const fn new(pos: u32, end: u32) -> Self {
41        Self { pos, end }
42    }
43}
44
45#[cfg(target_arch = "wasm32")]
46#[wasm_bindgen]
47impl TextRange {
48    /// Create a new text range.
49    /// All positions are character indices (not byte indices).
50    #[wasm_bindgen(constructor)]
51    #[must_use]
52    pub fn new(pos: u32, end: u32) -> Self {
53        Self { pos, end }
54    }
55}
56
57/// Index into an arena. Used instead of pointers/references for serialization-friendly graphs.
58#[wasm_bindgen]
59#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, Serialize, Deserialize, Hash)]
60pub struct NodeIndex(pub u32);
61
62impl NodeIndex {
63    pub const NONE: Self = Self(u32::MAX);
64
65    #[inline]
66    #[must_use]
67    pub const fn is_none(&self) -> bool {
68        self.0 == u32::MAX
69    }
70
71    #[inline]
72    #[must_use]
73    pub const fn is_some(&self) -> bool {
74        self.0 != u32::MAX
75    }
76}
77
78/// A list of node indices, representing children or a node array.
79#[derive(Clone, Debug, Default, Serialize, Deserialize)]
80pub struct NodeList {
81    pub nodes: Vec<NodeIndex>,
82    pub pos: u32,
83    pub end: u32,
84    pub has_trailing_comma: bool,
85}
86
87impl NodeList {
88    #[must_use]
89    pub const fn new() -> Self {
90        Self {
91            nodes: Vec::new(),
92            pos: 0,
93            end: 0,
94            has_trailing_comma: false,
95        }
96    }
97
98    #[must_use]
99    pub fn with_capacity(capacity: usize) -> Self {
100        Self {
101            nodes: Vec::with_capacity(capacity),
102            pos: 0,
103            end: 0,
104            has_trailing_comma: false,
105        }
106    }
107
108    pub fn push(&mut self, node: NodeIndex) {
109        self.nodes.push(node);
110    }
111
112    #[must_use]
113    pub const fn len(&self) -> usize {
114        self.nodes.len()
115    }
116
117    #[must_use]
118    pub const fn is_empty(&self) -> bool {
119        self.nodes.is_empty()
120    }
121}