1use crate::escape::{UnescapedRef, UnescapedRoute};
2use crate::tree::{denormalize_params, Node};
3
4use std::fmt;
5use std::ops::Deref;
6
7#[non_exhaustive]
9#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
10pub enum InsertError {
11 Conflict {
13 with: String,
15 },
16
17 InvalidParamSegment,
22
23 InvalidParam,
27
28 InvalidCatchAll,
30}
31
32impl fmt::Display for InsertError {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 match self {
35 Self::Conflict { with } => {
36 write!(
37 f,
38 "Insertion failed due to conflict with previously registered route: {with}"
39 )
40 }
41 Self::InvalidParamSegment => {
42 write!(f, "Only one parameter is allowed per path segment")
43 }
44 Self::InvalidParam => write!(f, "Parameters must be registered with a valid name"),
45 Self::InvalidCatchAll => write!(
46 f,
47 "Catch-all parameters are only allowed at the end of a route"
48 ),
49 }
50 }
51}
52
53impl std::error::Error for InsertError {}
54
55impl InsertError {
56 pub(crate) fn conflict<T>(
60 route: &UnescapedRoute,
61 prefix: UnescapedRef<'_>,
62 current: &Node<T>,
63 ) -> Self {
64 let mut route = route.clone();
65
66 if prefix.unescaped() == current.prefix.unescaped() {
68 denormalize_params(&mut route, ¤t.remapping);
69 return InsertError::Conflict {
70 with: String::from_utf8(route.into_unescaped()).unwrap(),
71 };
72 }
73
74 route.truncate(route.len() - prefix.len());
76
77 if !route.ends_with(¤t.prefix) {
79 route.append(¤t.prefix);
80 }
81
82 let mut child = current.children.first();
84 while let Some(node) = child {
85 route.append(&node.prefix);
86 child = node.children.first();
87 }
88
89 let mut last = current;
91 while let Some(node) = last.children.first() {
92 last = node;
93 }
94 denormalize_params(&mut route, &last.remapping);
95
96 InsertError::Conflict {
98 with: String::from_utf8(route.into_unescaped()).unwrap(),
99 }
100 }
101}
102
103#[derive(Clone, Debug, Eq, PartialEq)]
107pub struct MergeError(pub(crate) Vec<InsertError>);
108
109impl MergeError {
110 pub fn into_errors(self) -> Vec<InsertError> {
113 self.0
114 }
115}
116
117impl fmt::Display for MergeError {
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 for error in self.0.iter() {
120 writeln!(f, "{}", error)?;
121 }
122
123 Ok(())
124 }
125}
126
127impl std::error::Error for MergeError {}
128
129impl Deref for MergeError {
130 type Target = Vec<InsertError>;
131
132 fn deref(&self) -> &Self::Target {
133 &self.0
134 }
135}
136
137#[derive(Debug, PartialEq, Eq, Clone, Copy)]
153pub enum MatchError {
154 NotFound,
156}
157
158impl fmt::Display for MatchError {
159 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160 write!(f, "Matching route not found")
161 }
162}
163
164impl std::error::Error for MatchError {}