1use std::ops::Deref;
2
3use crate::graph::{Disambiguate, Fork, Graph, NodeId, Range};
4
5#[derive(PartialEq, Clone, Hash)]
6pub struct Rope {
7 pub pattern: Pattern,
8 pub then: NodeId,
9 pub miss: Miss,
10}
11
12#[derive(PartialEq, Clone, Hash)]
13pub struct Pattern(pub Vec<Range>);
14
15impl Deref for Pattern {
16 type Target = [Range];
17
18 fn deref(&self) -> &[Range] {
19 &self.0
20 }
21}
22
23#[derive(PartialEq, Clone, Copy, Hash)]
26pub enum Miss {
27 None,
29 First(NodeId),
31 Any(NodeId),
33}
34
35impl Miss {
36 pub fn is_none(&self) -> bool {
37 matches!(self, Miss::None)
38 }
39
40 pub fn first(self) -> Option<NodeId> {
41 match self {
42 Miss::First(id) | Miss::Any(id) => Some(id),
43 _ => None,
44 }
45 }
46
47 pub fn take_first(&mut self) -> Option<NodeId> {
48 match *self {
49 Miss::First(id) => {
50 *self = Miss::None;
51
52 Some(id)
53 }
54 Miss::Any(id) => Some(id),
55 Miss::None => None,
56 }
57 }
58}
59
60impl From<Option<NodeId>> for Miss {
61 fn from(miss: Option<NodeId>) -> Self {
62 match miss {
63 Some(id) => Miss::First(id),
64 None => Miss::None,
65 }
66 }
67}
68
69impl From<NodeId> for Miss {
70 fn from(id: NodeId) -> Self {
71 Miss::First(id)
72 }
73}
74
75impl Rope {
76 pub fn new<P>(pattern: P, then: NodeId) -> Self
77 where
78 P: Into<Pattern>,
79 {
80 Rope {
81 pattern: pattern.into(),
82 then,
83 miss: Miss::None,
84 }
85 }
86
87 pub fn miss<M>(mut self, miss: M) -> Self
88 where
89 M: Into<Miss>,
90 {
91 self.miss = miss.into();
92 self
93 }
94
95 pub fn miss_any(mut self, miss: NodeId) -> Self {
96 self.miss = Miss::Any(miss);
97 self
98 }
99
100 pub fn into_fork<T>(mut self, graph: &mut Graph<T>) -> Fork
101 where
102 T: Disambiguate,
103 {
104 let first = self.pattern.0.remove(0);
105 let miss = self.miss.take_first();
106
107 let then = match self.pattern.len() {
110 0 => self.then,
111 _ => graph.push(self),
112 };
113
114 Fork::new().branch(first, then).miss(miss)
115 }
116
117 pub fn prefix(&self, other: &Self) -> Option<(Pattern, Miss)> {
118 let count = self
119 .pattern
120 .iter()
121 .zip(other.pattern.iter())
122 .take_while(|(a, b)| a == b)
123 .count();
124
125 let pattern = match count {
126 0 => return None,
127 n => self.pattern[..n].into(),
128 };
129 let miss = match (self.miss, other.miss) {
130 (Miss::None, miss) => miss,
131 (miss, Miss::None) => miss,
132 _ => return None,
133 };
134
135 Some((pattern, miss))
136 }
137
138 pub fn split_at<T>(mut self, at: usize, graph: &mut Graph<T>) -> Option<Rope>
139 where
140 T: Disambiguate,
141 {
142 match at {
143 0 => return None,
144 n if n == self.pattern.len() => return Some(self),
145 _ => (),
146 }
147
148 let (this, next) = self.pattern.split_at(at);
149
150 let next_miss = match self.miss {
151 Miss::Any(_) => self.miss,
152 _ => Miss::None,
153 };
154
155 let next = graph.push(Rope {
156 pattern: next.into(),
157 miss: next_miss,
158 then: self.then,
159 });
160
161 self.pattern = this.into();
162 self.then = next;
163
164 Some(self)
165 }
166
167 pub fn remainder<T>(mut self, at: usize, graph: &mut Graph<T>) -> NodeId
168 where
169 T: Disambiguate,
170 {
171 self.pattern = self.pattern[at..].into();
172
173 match self.pattern.len() {
174 0 => self.then,
175 _ => graph.push(self),
176 }
177 }
178
179 pub fn shake<T>(&self, graph: &Graph<T>, filter: &mut [bool]) {
180 if let Some(id) = self.miss.first() {
181 if !filter[id.get()] {
182 filter[id.get()] = true;
183 graph[id].shake(graph, filter);
184 }
185 }
186
187 if !filter[self.then.get()] {
188 filter[self.then.get()] = true;
189 graph[self.then].shake(graph, filter);
190 }
191 }
192}
193
194impl Pattern {
195 pub fn to_bytes(&self) -> Option<Vec<u8>> {
196 let mut out = Vec::with_capacity(self.len());
197
198 for range in self.iter() {
199 out.push(range.as_byte()?);
200 }
201
202 Some(out)
203 }
204}
205
206impl<T> From<&[T]> for Pattern
207where
208 T: Into<Range> + Copy,
209{
210 fn from(slice: &[T]) -> Self {
211 Pattern(slice.iter().copied().map(Into::into).collect())
212 }
213}
214
215impl<T> From<Vec<T>> for Pattern
216where
217 T: Into<Range>,
218{
219 fn from(vec: Vec<T>) -> Self {
220 Pattern(vec.into_iter().map(Into::into).collect())
221 }
222}
223
224impl From<&str> for Pattern {
225 fn from(slice: &str) -> Self {
226 slice.as_bytes().into()
227 }
228}
229
230#[cfg(test)]
231mod tests {
232 use super::*;
233 use crate::graph::Node;
234 use pretty_assertions::assert_eq;
235
236 #[test]
237 fn into_fork() {
238 let mut graph = Graph::new();
239
240 let leaf = graph.push(Node::Leaf("LEAF"));
241 let rope = Rope::new("foobar", leaf);
242
243 let fork = rope.into_fork(&mut graph);
244
245 assert_eq!(leaf, NodeId::new(1));
246 assert_eq!(fork, Fork::new().branch(b'f', NodeId::new(2)));
247 assert_eq!(graph[NodeId::new(2)], Rope::new("oobar", leaf));
248 }
249
250 #[test]
251 fn into_fork_one_byte() {
252 let mut graph = Graph::new();
253
254 let leaf = graph.push(Node::Leaf("LEAF"));
255 let rope = Rope::new("!", leaf);
256
257 let fork = rope.into_fork(&mut graph);
258
259 assert_eq!(leaf, NodeId::new(1));
260 assert_eq!(fork, Fork::new().branch(b'!', NodeId::new(1)));
261 }
262
263 #[test]
264 fn into_fork_miss_any() {
265 let mut graph = Graph::new();
266
267 let leaf = graph.push(Node::Leaf("LEAF"));
268 let rope = Rope::new("42", leaf).miss_any(NodeId::new(42));
269
270 let fork = rope.into_fork(&mut graph);
271
272 assert_eq!(leaf, NodeId::new(1));
273 assert_eq!(
274 fork,
275 Fork::new()
276 .branch(b'4', NodeId::new(2))
277 .miss(NodeId::new(42))
278 );
279 assert_eq!(
280 graph[NodeId::new(2)],
281 Rope::new("2", leaf).miss_any(NodeId::new(42))
282 );
283 }
284
285 #[test]
286 fn into_fork_miss_first() {
287 let mut graph = Graph::new();
288
289 let leaf = graph.push(Node::Leaf("LEAF"));
290 let rope = Rope::new("42", leaf).miss(Miss::First(NodeId::new(42)));
291
292 let fork = rope.into_fork(&mut graph);
293
294 assert_eq!(leaf, NodeId::new(1));
295 assert_eq!(
296 fork,
297 Fork::new()
298 .branch(b'4', NodeId::new(2))
299 .miss(NodeId::new(42))
300 );
301 assert_eq!(graph[NodeId::new(2)], Rope::new("2", leaf));
302 }
303
304 #[test]
305 fn split_at() {
306 let mut graph = Graph::new();
307
308 let leaf = graph.push(Node::Leaf("LEAF"));
309 let rope = Rope::new("foobar", leaf);
310
311 assert_eq!(rope.clone().split_at(6, &mut graph).unwrap(), rope);
312
313 let split = rope.split_at(3, &mut graph).unwrap();
314 let expected_id = NodeId::new(leaf.get() + 1);
315
316 assert_eq!(split, Rope::new("foo", expected_id));
317 assert_eq!(graph[expected_id], Rope::new("bar", leaf));
318 }
319
320 #[test]
321 fn pattern_to_bytes() {
322 let pat = Pattern::from("foobar");
323
324 assert_eq!(pat.to_bytes().unwrap(), b"foobar");
325
326 let ranges = Pattern::from(vec![0..=0, 42..=42, b'{'..=b'}']);
327
328 assert_eq!(ranges.to_bytes(), None);
329 }
330}