1use std::sync::Arc;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{ClassItem, ClassSet, Cursor, NodeId, ParseError, Span};
6
7#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
8pub struct Node {
9 pub kind: AstKind,
10 pub span: Span,
11 pub parent: Option<NodeId>,
12}
13
14#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
15#[serde(tag = "type", rename_all = "snake_case")]
16pub enum AstKind {
17 Empty,
18 Anchor {
19 kind: AnchorKind,
20 },
21 Literal {
22 c: char,
23 escaped: bool,
24 },
25 Dot,
26 Class {
27 negated: bool,
28 items: Vec<ClassItem>,
29 set: ClassSet,
30 },
31 Group {
32 kind: GroupKind,
33 inner: NodeId,
34 },
35 Alt {
36 arms: Vec<NodeId>,
37 },
38 Concat {
39 parts: Vec<NodeId>,
40 },
41 Repeat {
42 inner: NodeId,
43 kind: RepKind,
44 greedy: bool,
45 },
46}
47
48impl AstKind {
49 #[must_use]
50 pub fn children(&self) -> &[NodeId] {
51 match self {
52 Self::Group { inner, .. } | Self::Repeat { inner, .. } => std::slice::from_ref(inner),
53 Self::Alt { arms } => arms,
54 Self::Concat { parts } => parts,
55 Self::Empty
56 | Self::Anchor { .. }
57 | Self::Literal { .. }
58 | Self::Dot
59 | Self::Class { .. } => &[],
60 }
61 }
62}
63
64#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
65#[serde(rename_all = "snake_case")]
66pub enum AnchorKind {
67 Start,
68 End,
69}
70
71#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
72#[serde(tag = "kind", rename_all = "snake_case")]
73pub enum GroupKind {
74 Capture { index: u32, name: Option<Box<str>> },
75 NonCapture,
76}
77
78#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
79#[serde(tag = "kind", rename_all = "snake_case")]
80pub enum RepKind {
81 ZeroOrOne,
82 ZeroOrMore,
83 OneOrMore,
84 Range { min: u32, max: Option<u32> },
85}
86
87#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
88pub struct GroupInfo {
89 pub index: u32,
90 pub name: Option<Box<str>>,
91 pub node: NodeId,
92}
93
94#[derive(Clone, Debug)]
96pub struct Pattern {
97 pub(crate) src: Arc<str>,
98 pub(crate) nodes: Vec<Node>,
99 pub(crate) groups: Vec<GroupInfo>,
100 pub(crate) root: NodeId,
101}
102
103impl Pattern {
104 pub fn parse(src: &str) -> Result<Self, ParseError> {
110 crate::parse(src)
111 }
112
113 #[must_use]
114 pub fn source(&self) -> &str {
115 &self.src
116 }
117
118 #[must_use]
119 pub const fn root_id(&self) -> NodeId {
120 self.root
121 }
122
123 #[must_use]
124 pub fn root(&self) -> Cursor<'_> {
125 Cursor::new(self, self.root)
126 }
127
128 #[must_use]
129 pub fn node(&self, id: NodeId) -> &Node {
130 &self.nodes[id.0 as usize]
131 }
132
133 #[must_use]
134 pub fn nodes(&self) -> &[Node] {
135 &self.nodes
136 }
137
138 #[must_use]
139 pub fn groups(&self) -> &[GroupInfo] {
140 &self.groups
141 }
142
143 #[must_use]
144 pub fn len(&self) -> usize {
145 self.nodes.len()
146 }
147
148 #[must_use]
149 pub fn is_empty(&self) -> bool {
150 self.nodes.is_empty()
151 }
152
153 #[must_use]
154 pub fn text(&self, span: Span) -> &str {
155 &self.src[span.start as usize..span.end as usize]
156 }
157}