1use core::{error, fmt, ops::Deref};
2
3use crate::{
4 String, Vec,
5 escape::{UnescapedRef, UnescapedRoute},
6 tree::{Node, denormalize_params},
7};
8
9#[non_exhaustive]
11#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
12pub enum InsertError {
13 Conflict {
15 with: String,
17 },
18
19 InvalidParamSegment,
24
25 InvalidParam,
29
30 InvalidCatchAll,
32}
33
34impl fmt::Display for InsertError {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 let fmt = match self {
37 Self::Conflict { with } => {
38 return write!(
39 f,
40 "Insertion failed due to conflict with previously registered route: {with}"
41 );
42 }
43 Self::InvalidParamSegment => "Only one parameter is allowed per path segment",
44 Self::InvalidParam => "Parameters must be registered with a valid name",
45 Self::InvalidCatchAll => "Catch-all parameters are only allowed at the end of a route",
46 };
47 fmt::Display::fmt(fmt, f)
48 }
49}
50
51impl error::Error for InsertError {}
52
53impl InsertError {
54 pub(crate) fn conflict<T>(route: &UnescapedRoute, prefix: UnescapedRef<'_>, current: &Node<T>) -> Self {
58 let mut route = route.clone();
59
60 if *prefix == *current.prefix {
62 denormalize_params(&mut route, ¤t.remapping);
63 return InsertError::Conflict {
64 with: route.into_unescaped(),
65 };
66 }
67
68 route.truncate(route.len() - prefix.len());
70
71 if !route.ends_with(¤t.prefix) {
73 route.append(¤t.prefix);
74 }
75
76 let mut child = current.children.first();
78 while let Some(node) = child {
79 route.append(&node.prefix);
80 child = node.children.first();
81 }
82
83 let mut last = current;
85 while let Some(node) = last.children.first() {
86 last = node;
87 }
88 denormalize_params(&mut route, &last.remapping);
89
90 InsertError::Conflict {
92 with: route.into_unescaped(),
93 }
94 }
95}
96
97#[derive(Clone, Debug, Eq, PartialEq)]
101pub struct MergeError(pub(crate) Vec<InsertError>);
102
103impl MergeError {
104 pub fn into_errors(self) -> Vec<InsertError> {
107 self.0
108 }
109}
110
111impl fmt::Display for MergeError {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 for error in self.0.iter() {
114 writeln!(f, "{error}")?;
115 }
116
117 Ok(())
118 }
119}
120
121impl error::Error for MergeError {}
122
123impl Deref for MergeError {
124 type Target = [InsertError];
125
126 fn deref(&self) -> &Self::Target {
127 &self.0
128 }
129}
130
131#[derive(Debug, PartialEq, Eq, Clone, Copy)]
147pub struct MatchError;
148
149impl fmt::Display for MatchError {
150 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151 fmt::Display::fmt("Matching route not found", f)
152 }
153}
154
155impl error::Error for MatchError {}