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!(f, "Catch-all parameters are only allowed at the end of a route"),
46 }
47 }
48}
49
50impl std::error::Error for InsertError {}
51
52impl InsertError {
53 pub(crate) fn conflict<T>(route: &UnescapedRoute, prefix: UnescapedRef<'_>, current: &Node<T>) -> Self {
57 let mut route = route.clone();
58
59 if prefix.unescaped() == current.prefix.unescaped() {
61 denormalize_params(&mut route, ¤t.remapping);
62 return InsertError::Conflict {
63 with: String::from_utf8(route.into_unescaped()).unwrap(),
64 };
65 }
66
67 route.truncate(route.len() - prefix.len());
69
70 if !route.ends_with(¤t.prefix) {
72 route.append(¤t.prefix);
73 }
74
75 let mut child = current.children.first();
77 while let Some(node) = child {
78 route.append(&node.prefix);
79 child = node.children.first();
80 }
81
82 let mut last = current;
84 while let Some(node) = last.children.first() {
85 last = node;
86 }
87 denormalize_params(&mut route, &last.remapping);
88
89 InsertError::Conflict {
91 with: String::from_utf8(route.into_unescaped()).unwrap(),
92 }
93 }
94}
95
96#[derive(Clone, Debug, Eq, PartialEq)]
100pub struct MergeError(pub(crate) Vec<InsertError>);
101
102impl MergeError {
103 pub fn into_errors(self) -> Vec<InsertError> {
106 self.0
107 }
108}
109
110impl fmt::Display for MergeError {
111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112 for error in self.0.iter() {
113 writeln!(f, "{error}")?;
114 }
115
116 Ok(())
117 }
118}
119
120impl std::error::Error for MergeError {}
121
122impl Deref for MergeError {
123 type Target = Vec<InsertError>;
124
125 fn deref(&self) -> &Self::Target {
126 &self.0
127 }
128}
129
130#[derive(Debug, PartialEq, Eq, Clone, Copy)]
146pub struct MatchError;
147
148impl fmt::Display for MatchError {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 write!(f, "Matching route not found")
151 }
152}
153
154impl std::error::Error for MatchError {}