1use std::fmt;
2
3#[derive(Debug)]
6pub struct PathDeserializationError {
7 pub(crate) kind: ErrorKind,
8}
9
10impl PathDeserializationError {
11 pub(crate) fn new(kind: ErrorKind) -> Self {
12 Self { kind }
13 }
14
15 pub(crate) fn wrong_number_of_parameters() -> WrongNumberOfParameters<()> {
16 WrongNumberOfParameters { got: () }
17 }
18
19 #[track_caller]
20 pub(crate) fn unsupported_type(name: &'static str) -> Self {
21 Self::new(ErrorKind::UnsupportedType { name })
22 }
23}
24
25pub(crate) struct WrongNumberOfParameters<G> {
26 got: G,
27}
28
29impl<G> WrongNumberOfParameters<G> {
30 #[allow(clippy::unused_self)]
31 pub(crate) fn got<G2>(self, got: G2) -> WrongNumberOfParameters<G2> {
32 WrongNumberOfParameters { got }
33 }
34}
35
36impl WrongNumberOfParameters<usize> {
37 pub(crate) fn expected(self, expected: usize) -> PathDeserializationError {
38 PathDeserializationError::new(ErrorKind::WrongNumberOfParameters {
39 got: self.got,
40 expected,
41 })
42 }
43}
44
45impl serde::de::Error for PathDeserializationError {
46 #[inline]
47 fn custom<T>(msg: T) -> Self
48 where
49 T: fmt::Display,
50 {
51 Self {
52 kind: ErrorKind::Message(msg.to_string()),
53 }
54 }
55}
56
57impl fmt::Display for PathDeserializationError {
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 self.kind.fmt(f)
60 }
61}
62
63impl std::error::Error for PathDeserializationError {}
64
65#[derive(Debug, PartialEq, Eq)]
71#[non_exhaustive]
72pub enum ErrorKind {
73 WrongNumberOfParameters {
75 got: usize,
77 expected: usize,
79 },
80
81 ParseErrorAtKey {
85 key: String,
87 value: String,
89 expected_type: &'static str,
91 },
92
93 ParseErrorAtIndex {
97 index: usize,
99 value: String,
101 expected_type: &'static str,
103 },
104
105 ParseError {
109 value: String,
111 expected_type: &'static str,
113 },
114
115 InvalidUtf8InPathParam {
117 key: String,
119 },
120
121 UnsupportedType {
126 name: &'static str,
128 },
129
130 Message(String),
132}
133
134impl fmt::Display for ErrorKind {
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 match self {
137 ErrorKind::Message(error) => error.fmt(f),
138 ErrorKind::InvalidUtf8InPathParam { key } => write!(f, "Invalid UTF-8 in `{key}`"),
139 ErrorKind::WrongNumberOfParameters { got, expected } => {
140 write!(
141 f,
142 "Wrong number of path arguments for `Path`. Expected {expected} but got {got}"
143 )?;
144
145 if *expected == 1 {
146 write!(f, ". Note that multiple parameters must be extracted with a tuple `Path<(_, _)>` or a struct `Path<YourParams>`")?;
147 }
148
149 Ok(())
150 }
151 ErrorKind::UnsupportedType { name } => write!(f, "Unsupported type `{name}`"),
152 ErrorKind::ParseErrorAtKey {
153 key,
154 value,
155 expected_type,
156 } => write!(
157 f,
158 "Cannot parse `{key}` with value `{value:?}` to a `{expected_type}`"
159 ),
160 ErrorKind::ParseError {
161 value,
162 expected_type,
163 } => write!(f, "Cannot parse `{value:?}` to a `{expected_type}`"),
164 ErrorKind::ParseErrorAtIndex {
165 index,
166 value,
167 expected_type,
168 } => write!(
169 f,
170 "Cannot parse value at index {index} with value `{value:?}` to a `{expected_type}`"
171 ),
172 }
173 }
174}