1use crate::escape::{UnescapedRef, UnescapedRoute};
2use crate::tree::{denormalize_params, Node};
3
4use std::fmt;
5
6#[non_exhaustive]
8#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
9pub enum InsertError {
10 Conflict {
12 with: String,
14 },
15 InvalidParamSegment,
20 InvalidParam,
24 InvalidCatchAll,
26}
27
28impl fmt::Display for InsertError {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 match self {
31 Self::Conflict { with } => {
32 write!(
33 f,
34 "Insertion failed due to conflict with previously registered route: {}",
35 with
36 )
37 }
38 Self::InvalidParamSegment => {
39 write!(f, "Only one parameter is allowed per path segment")
40 }
41 Self::InvalidParam => write!(f, "Parameters must be registered with a valid name"),
42 Self::InvalidCatchAll => write!(
43 f,
44 "Catch-all parameters are only allowed at the end of a route"
45 ),
46 }
47 }
48}
49
50impl std::error::Error for InsertError {}
51
52impl InsertError {
53 pub(crate) fn conflict<T>(
57 route: &UnescapedRoute,
58 prefix: UnescapedRef<'_>,
59 current: &Node<T>,
60 ) -> Self {
61 let mut route = route.clone();
62
63 if prefix.unescaped() == current.prefix.unescaped() {
65 denormalize_params(&mut route, ¤t.remapping);
66 return InsertError::Conflict {
67 with: String::from_utf8(route.into_unescaped()).unwrap(),
68 };
69 }
70
71 route.truncate(route.len() - prefix.len());
73
74 if !route.ends_with(¤t.prefix) {
76 route.append(¤t.prefix);
77 }
78
79 let mut child = current.children.first();
81 while let Some(node) = child {
82 route.append(&node.prefix);
83 child = node.children.first();
84 }
85
86 let mut last = current;
88 while let Some(node) = last.children.first() {
89 last = node;
90 }
91 denormalize_params(&mut route, &last.remapping);
92
93 InsertError::Conflict {
95 with: String::from_utf8(route.into_unescaped()).unwrap(),
96 }
97 }
98}
99
100#[derive(Debug, PartialEq, Eq, Clone, Copy)]
116pub enum MatchError {
117 NotFound,
119}
120
121impl fmt::Display for MatchError {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 write!(f, "Matching route not found")
124 }
125}
126
127impl std::error::Error for MatchError {}