1use alloc::{string::String, vec::Vec};
2use core::{
3 cmp::Ordering,
4 fmt::{self, Write},
5 ops::Range,
6};
7
8use smallvec::SmallVec;
9
10use crate::Kind;
11
12#[derive(Clone, Debug, PartialEq, Eq)]
13pub enum Key {
14 String(Vec<u8>),
15 Parameter(Kind),
16}
17
18#[derive(Clone)]
19pub struct Node<T> {
20 pub key: Key,
21 pub value: Option<T>,
22 pub nodes0: Option<Vec<Self>>,
24 pub nodes1: Option<Vec<Self>>,
26}
27
28impl<T: fmt::Debug> Node<T> {
29 pub fn new(key: Key, value: Option<T>) -> Self {
30 Self {
31 key,
32 value,
33 nodes0: None,
34 nodes1: None,
35 }
36 }
37
38 pub fn insert_bytes(&mut self, mut bytes: &[u8]) -> &mut Self {
39 let diff = match &mut self.key {
40 Key::String(s) => {
41 if s.is_empty() {
42 *s = bytes.to_vec();
43 return self;
44 }
45
46 let cursor = s
47 .iter()
48 .zip(bytes.iter())
49 .take_while(|(a, b)| a == b)
50 .count();
51
52 if cursor == 0 {
53 true
54 } else {
55 if cursor < s.len() {
57 let (prefix, suffix) = s.split_at(cursor);
58 let mut node = Node::new(Key::String(prefix.to_vec()), None);
59 *s = suffix.to_vec();
60 ::core::mem::swap(self, &mut node);
61 self.nodes0.get_or_insert_with(Vec::new).push(node);
62 }
63 if cursor == bytes.len() {
64 false
65 } else {
66 bytes = &bytes[cursor..];
67 true
68 }
69 }
70 }
71 Key::Parameter(_) => true,
72 };
73
74 if diff {
76 let nodes = self.nodes0.get_or_insert_with(Vec::new);
77 return match nodes.binary_search_by(|node| match &node.key {
78 Key::String(s) => {
79 compare(s[0], bytes[0])
83 }
84 Key::Parameter(_) => unreachable!(),
85 }) {
86 Ok(i) => nodes[i].insert_bytes(bytes),
87 Err(i) => {
88 nodes.insert(i, Node::new(Key::String(bytes.to_vec()), None));
89 &mut nodes[i]
90 }
91 };
92 }
93
94 self
95 }
96
97 pub fn insert_parameter(&mut self, kind: Kind) -> &mut Self {
98 let nodes = self.nodes1.get_or_insert_with(Vec::new);
99 let i = nodes
100 .binary_search_by(|node| match node.key {
101 Key::Parameter(pk) => pk.cmp(&kind),
102 Key::String(_) => unreachable!(),
103 })
104 .unwrap_or_else(|i| {
105 nodes.insert(i, Node::new(Key::Parameter(kind), None));
106 i
107 });
108 &mut nodes[i]
109 }
110
111 #[allow(clippy::range_plus_one)]
112 #[allow(clippy::too_many_lines)]
113 #[inline]
114 fn find_with(
115 &self,
116 mut start: usize,
117 mut bytes: &[u8],
118 ranges: &mut SmallVec<[Range<usize>; 8]>,
119 ) -> Option<&T> {
120 let mut m = bytes.len();
121 match &self.key {
122 Key::String(s) => {
123 let n = s.len();
124 let mut flag = m >= n;
125
126 if flag {
128 if n == 1 {
129 flag = s[0] == bytes[0];
130 } else {
131 flag = s == &bytes[..n];
132 }
133 }
134
135 if flag {
137 m -= n;
138 start += n;
139 bytes = &bytes[n..];
140
141 if m == 0 {
142 if let Some(id) = &self.value {
143 return Some(id);
144 }
145 } else {
146 if let Some(id) = self.nodes0.as_ref().and_then(|nodes| {
148 nodes
149 .binary_search_by(|node| match &node.key {
150 Key::String(s) => {
151 compare(s[0], bytes[0])
155 }
156 Key::Parameter(_) => unreachable!(),
157 })
158 .ok()
159 .and_then(|i| nodes[i].find_with(start, bytes, ranges))
160 }) {
161 return Some(id);
162 }
163 }
164
165 if let Some(id) = self.nodes1.as_ref().and_then(|nodes| {
167 let b = m > 0;
168 nodes
169 .iter()
170 .filter(|node| match node.key {
171 Key::Parameter(pk)
172 if pk == Kind::Normal || pk == Kind::OneOrMore =>
173 {
174 b
175 }
176 _ => true,
177 })
178 .find_map(|node| node.find_with(start, bytes, ranges))
179 }) {
180 return Some(id);
181 }
182 } else if n == 1 && s[0] == b'/' {
183 if let Some(id) = self.nodes1.as_ref().and_then(|nodes| {
184 nodes
185 .iter()
186 .filter(|node| {
187 matches!(node.key,
188 Key::Parameter(pk)
189 if pk == Kind::OptionalSegment
190 || pk == Kind::ZeroOrMoreSegment
191 )
192 })
193 .find_map(|node| node.find_with(start, bytes, ranges))
194 }) {
195 return Some(id);
196 }
197 }
198 }
199 Key::Parameter(k) => match k {
200 Kind::Normal | Kind::Optional | Kind::OptionalSegment => {
201 if m == 0 {
202 if k == &Kind::Normal {
203 return None;
204 }
205
206 if self.nodes0.is_none() && self.nodes1.is_none() {
208 return self.value.as_ref().inspect(|_| {
209 ranges.push(start..start);
210 });
211 }
212 } else {
213 if let Some(id) = self.nodes0.as_ref().and_then(|nodes| {
215 nodes.iter().find_map(|node| match &node.key {
216 Key::String(s) => {
217 let mut keep_running = true;
218 bytes
219 .iter()
220 .take_while(|b| {
223 if keep_running && **b == b'/' {
224 keep_running = false;
225 true
226 } else {
227 keep_running
228 }
229 })
230 .enumerate()
231 .filter_map(|(n, b)| (s[0] == *b).then_some(n))
232 .find_map(|n| {
233 node.find_with(start + n, &bytes[n..], ranges).inspect(
234 |_| {
235 ranges.push(start..start + n);
236 },
237 )
238 })
239 }
240 Key::Parameter(_) => unreachable!(),
241 })
242 }) {
243 return Some(id);
244 }
245
246 if let Some(id) = self.nodes1.as_ref().and_then(|nodes| {
248 let b = m - 1 > 0;
249 nodes
250 .iter()
251 .filter(|node| match node.key {
252 Key::Parameter(pk)
253 if pk == Kind::Normal || pk == Kind::OneOrMore =>
254 {
255 b
256 }
257 _ => true,
258 })
259 .find_map(|node| node.find_with(start + 1, &bytes[1..], ranges))
260 }) {
261 ranges.push(start..start + 1);
262 return Some(id);
263 }
264 }
265
266 if k == &Kind::Optional || k == &Kind::OptionalSegment {
268 if let Some(id) = self.nodes1.as_ref().and_then(|nodes| {
269 let b = m > 0;
270 nodes
271 .iter()
272 .filter(|node| match &node.key {
273 Key::Parameter(pk)
274 if pk == &Kind::Normal || pk == &Kind::OneOrMore =>
275 {
276 b
277 }
278 _ => true,
279 })
280 .find_map(|node| node.find_with(start, bytes, ranges))
281 }) {
282 ranges.push(start + m..start + m);
284 return Some(id);
285 }
286 }
287
288 if let Some(n) = bytes.iter().position(|b| *b == b'/') {
289 bytes = &bytes[n..];
290 } else {
291 if let Some(id) = &self.value {
292 ranges.push(start..start + m);
293 return Some(id);
294 }
295 bytes = &bytes[m..];
296 }
297
298 if k == &Kind::OptionalSegment {
299 if let Some(id) = self.nodes0.as_ref().and_then(|nodes| {
300 nodes
301 .last()
302 .filter(|node| match &node.key {
303 Key::String(s) => s[0] == b'/',
304 Key::Parameter(_) => unreachable!(),
305 })
306 .and_then(|node| node.find_with(start, bytes, ranges))
307 }) {
308 ranges.push(start..start + m);
309 return Some(id);
310 }
311 }
312 }
313 Kind::OneOrMore | Kind::ZeroOrMore | Kind::ZeroOrMoreSegment => {
314 let is_one_or_more = k == &Kind::OneOrMore;
315 if m == 0 {
316 if is_one_or_more {
317 return None;
318 }
319
320 if self.nodes0.is_none() && self.nodes1.is_none() {
321 return self.value.as_ref().inspect(|_| {
322 ranges.push(start..start);
323 });
324 }
325 } else {
326 if self.nodes0.is_none() && self.nodes1.is_none() {
327 if let Some(id) = &self.value {
328 ranges.push(start..start + m);
329 return Some(id);
330 }
331 }
332
333 if let Some(id) = self.nodes0.as_ref().and_then(|nodes| {
335 nodes.iter().find_map(|node| {
336 if let Key::String(s) = &node.key {
337 let right_length = if is_one_or_more {
338 m > s.len()
339 } else {
340 m >= s.len()
341 };
342 if right_length {
343 return bytes
344 .iter()
345 .enumerate()
346 .filter_map(|(n, b)| (s[0] == *b).then_some(n))
347 .find_map(|n| {
348 node.find_with(start + n, &bytes[n..], ranges)
349 .inspect(|_| {
350 ranges.push(start..start + n);
351 })
352 });
353 }
354 }
355 None
356 })
357 }) {
358 return Some(id);
359 }
360 }
361
362 if k == &Kind::ZeroOrMoreSegment {
363 if let Some(id) = self.nodes0.as_ref().and_then(|nodes| {
364 nodes
365 .last()
366 .filter(|node| match &node.key {
367 Key::String(s) => s[0] == b'/',
368 Key::Parameter(_) => unreachable!(),
369 })
370 .and_then(|node| node.find_with(start, bytes, ranges))
371 }) {
372 ranges.push(start + m..start + m);
374 return Some(id);
375 }
376 }
377 }
378 },
379 }
380 None
381 }
382
383 pub fn find(&self, bytes: &[u8]) -> Option<(&T, SmallVec<[Range<usize>; 8]>)> {
384 let mut ranges = SmallVec::<[Range<usize>; 8]>::new_const(); self.find_with(0, bytes, &mut ranges).map(|t| (t, ranges))
386 }
387}
388
389impl<T: fmt::Debug> fmt::Debug for Node<T> {
390 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
391 const EDGE: &str = "├──";
392 const LINE: &str = "│ ";
393 const CORNER: &str = "└──";
394 const BLANK: &str = " ";
395
396 fn print_nodes<T: fmt::Debug>(
397 f: &mut fmt::Formatter<'_>,
398 nodes: &[Node<T>],
399 check: bool,
400 pad: &str,
401 space: &str,
402 ) -> fmt::Result {
403 for (index, node) in nodes.iter().enumerate() {
404 let (left, right) = if check && index == nodes.len() - 1 {
405 (BLANK, CORNER)
406 } else {
407 (LINE, EDGE)
408 };
409 f.write_str(pad)?;
410 f.write_str(space)?;
411 f.write_str(right)?;
412 let mut s = String::new();
413 s.push_str(pad);
414 s.push_str(space);
415 s.push_str(left);
416 print_tree(f, node, false, &s)?;
417 }
418 Ok(())
419 }
420
421 fn print_tree<T: fmt::Debug>(
422 f: &mut fmt::Formatter<'_>,
423 node: &Node<T>,
424 root: bool,
425 pad: &str,
426 ) -> fmt::Result {
427 let space = if root {
428 f.write_char('\n')?;
429 ""
430 } else {
431 f.write_char(' ')?;
432 " "
433 };
434 match &node.key {
435 Key::String(path) => {
436 f.write_str(
437 &String::from_utf8_lossy(path)
438 .replace(':', "\\:")
439 .replace('?', "\\?")
440 .replace('+', "\\+"),
441 )?;
442 }
443 Key::Parameter(kind) => {
444 let c = match kind {
445 Kind::Normal => ':',
446 Kind::Optional => '?',
447 Kind::OptionalSegment => {
448 f.write_char('?')?;
449 '?'
450 }
451 Kind::OneOrMore => '+',
452 Kind::ZeroOrMore => '*',
453 Kind::ZeroOrMoreSegment => {
454 f.write_char('*')?;
455 '*'
456 }
457 };
458 f.write_char(c)?;
459 }
460 }
461 if let Some(value) = &node.value {
462 f.write_str(" •")?;
463 value.fmt(f)?;
464 }
465 f.write_char('\n')?;
466
467 if let Some(nodes) = &node.nodes0 {
469 print_nodes(f, nodes, node.nodes1.is_none(), pad, space)?;
470 }
471
472 if let Some(nodes) = &node.nodes1 {
474 print_nodes(f, nodes, true, pad, space)?;
475 }
476
477 Ok(())
478 }
479
480 print_tree(f, self, true, "")
481 }
482}
483
484#[inline]
485fn compare(a: u8, b: u8) -> Ordering {
486 if a == b {
487 Ordering::Equal
488 } else if a == b'/' {
489 Ordering::Greater
490 } else if b == b'/' {
491 Ordering::Less
492 } else {
493 a.cmp(&b)
494 }
495}