1pub trait FromRoute<'de>: Sized {
51 fn parse_path_variable(slice: &'de str) -> Option<Self>;
62}
63
64impl<'de> FromRoute<'de> for bool {
65 fn parse_path_variable(slice: &'de str) -> Option<Self> {
66 match slice {
67 "true" => Some(true),
68 "false" => Some(false),
69 _ => None,
70 }
71 }
72}
73
74impl<'de> FromRoute<'de> for u8 {
75 fn parse_path_variable(slice: &'de str) -> Option<Self> {
76 slice.parse().ok()
77 }
78}
79
80impl<'de> FromRoute<'de> for u16 {
81 fn parse_path_variable(slice: &'de str) -> Option<Self> {
82 slice.parse().ok()
83 }
84}
85
86impl<'de> FromRoute<'de> for u32 {
87 fn parse_path_variable(slice: &'de str) -> Option<Self> {
88 slice.parse().ok()
89 }
90}
91
92impl<'de> FromRoute<'de> for u64 {
93 fn parse_path_variable(slice: &'de str) -> Option<Self> {
94 slice.parse().ok()
95 }
96}
97
98impl<'de> FromRoute<'de> for u128 {
99 fn parse_path_variable(slice: &'de str) -> Option<Self> {
100 slice.parse().ok()
101 }
102}
103
104impl<'de> FromRoute<'de> for usize {
105 fn parse_path_variable(slice: &'de str) -> Option<Self> {
106 slice.parse().ok()
107 }
108}
109
110impl<'de> FromRoute<'de> for i8 {
111 fn parse_path_variable(slice: &'de str) -> Option<Self> {
112 slice.parse().ok()
113 }
114}
115
116impl<'de> FromRoute<'de> for i16 {
117 fn parse_path_variable(slice: &'de str) -> Option<Self> {
118 slice.parse().ok()
119 }
120}
121
122impl<'de> FromRoute<'de> for i32 {
123 fn parse_path_variable(slice: &'de str) -> Option<Self> {
124 slice.parse().ok()
125 }
126}
127
128impl<'de> FromRoute<'de> for i64 {
129 fn parse_path_variable(slice: &'de str) -> Option<Self> {
130 slice.parse().ok()
131 }
132}
133
134impl<'de> FromRoute<'de> for i128 {
135 fn parse_path_variable(slice: &'de str) -> Option<Self> {
136 slice.parse().ok()
137 }
138}
139
140impl<'de> FromRoute<'de> for isize {
141 fn parse_path_variable(slice: &'de str) -> Option<Self> {
142 slice.parse().ok()
143 }
144}
145
146impl<'de> FromRoute<'de> for f32 {
147 fn parse_path_variable(slice: &'de str) -> Option<Self> {
148 slice.parse().ok()
149 }
150}
151
152impl<'de> FromRoute<'de> for f64 {
153 fn parse_path_variable(slice: &'de str) -> Option<Self> {
154 slice.parse().ok()
155 }
156}
157
158impl<'de> FromRoute<'de> for &'de [u8] {
159 fn parse_path_variable(slice: &'de str) -> Option<Self> {
160 Some(slice.as_bytes())
161 }
162}
163
164impl<'de> FromRoute<'de> for &'de str {
165 fn parse_path_variable(slice: &'de str) -> Option<Self> {
166 Some(slice)
167 }
168}
169
170impl<'de> FromRoute<'de> for String {
171 fn parse_path_variable(slice: &'de str) -> Option<Self> {
172 Some(slice.to_owned())
173 }
174}
175
176#[cfg(test)]
177mod tests {
178 use super::FromRoute;
179 use rstest::rstest;
180
181 #[rstest]
182 #[case("true", Some(true))]
183 #[case("false", Some(false))]
184 #[case("other", None)]
185 fn test_bool(#[case] input: &str, #[case] expected: Option<bool>) {
186 assert_eq!(bool::parse_path_variable(input), expected);
187 }
188
189 #[rstest]
190 #[case("42", Some(42))]
191 #[case("255", Some(255))]
192 #[case("-1", None)]
193 #[case("256", None)]
194 fn test_u8(#[case] input: &str, #[case] expected: Option<u8>) {
195 assert_eq!(u8::parse_path_variable(input), expected);
196 }
197
198 #[rstest]
199 #[case("42", Some(42))]
200 #[case("65535", Some(65535))]
201 #[case("-1", None)]
202 #[case("65536", None)]
203 fn test_u16(#[case] input: &str, #[case] expected: Option<u16>) {
204 assert_eq!(u16::parse_path_variable(input), expected);
205 }
206
207 #[rstest]
208 #[case("42", Some(42))]
209 #[case("4294967295", Some(4294967295))]
210 #[case("-1", None)]
211 #[case("4294967296", None)]
212 fn test_u32(#[case] input: &str, #[case] expected: Option<u32>) {
213 assert_eq!(u32::parse_path_variable(input), expected);
214 }
215
216 #[rstest]
217 #[case("42", Some(42))]
218 #[case("18446744073709551615", Some(18446744073709551615))]
219 #[case("-1", None)]
220 #[case("18446744073709551616", None)]
221 fn test_u64(#[case] input: &str, #[case] expected: Option<u64>) {
222 assert_eq!(u64::parse_path_variable(input), expected);
223 }
224
225 #[test]
226 fn test_usize() {
227 assert_eq!(usize::parse_path_variable("42"), Some(42_usize));
228 }
229
230 #[rstest]
231 #[case("42", Some(42))]
232 #[case(
233 "340282366920938463463374607431768211455",
234 Some(340282366920938463463374607431768211455)
235 )]
236 #[case("-1", None)]
237 #[case("340282366920938463463374607431768211456", None)]
238 fn test_u128(#[case] input: &str, #[case] expected: Option<u128>) {
239 assert_eq!(u128::parse_path_variable(input), expected);
240 }
241
242 #[rstest]
243 #[case("42", Some(42))]
244 #[case("-42", Some(-42))]
245 #[case("127", Some(127))]
246 #[case("-128", Some(-128))]
247 #[case("128", None)]
248 #[case("-129", None)]
249 fn test_i8(#[case] input: &str, #[case] expected: Option<i8>) {
250 assert_eq!(i8::parse_path_variable(input), expected);
251 }
252
253 #[rstest]
254 #[case("42", Some(42))]
255 #[case("-42", Some(-42))]
256 #[case("32767", Some(32767))]
257 #[case("-32768", Some(-32768))]
258 #[case("32768", None)]
259 #[case("-32769", None)]
260 fn test_i16(#[case] input: &str, #[case] expected: Option<i16>) {
261 assert_eq!(i16::parse_path_variable(input), expected);
262 }
263
264 #[rstest]
265 #[case("42", Some(42))]
266 #[case("-42", Some(-42))]
267 #[case("2147483647", Some(2147483647))]
268 #[case("-2147483648", Some(-2147483648))]
269 #[case("2147483648", None)]
270 #[case("-2147483649", None)]
271 fn test_i32(#[case] input: &str, #[case] expected: Option<i32>) {
272 assert_eq!(i32::parse_path_variable(input), expected);
273 }
274
275 #[rstest]
276 #[case("42", Some(42))]
277 #[case("-42", Some(-42))]
278 #[case("9223372036854775807", Some(9223372036854775807))]
279 #[case("-9223372036854775808", Some(-9223372036854775808))]
280 #[case("9223372036854775808", None)]
281 #[case("-9223372036854775809", None)]
282 fn test_i64(#[case] input: &str, #[case] expected: Option<i64>) {
283 assert_eq!(i64::parse_path_variable(input), expected);
284 }
285
286 #[rstest]
287 #[case("42", Some(42))]
288 #[case("-42", Some(-42))]
289 #[case(
290 "170141183460469231731687303715884105727",
291 Some(170141183460469231731687303715884105727)
292 )]
293 #[case("-170141183460469231731687303715884105728", Some(-170141183460469231731687303715884105728))]
294 #[case("170141183460469231731687303715884105728", None)]
295 #[case("-170141183460469231731687303715884105729", None)]
296 fn test_i128(#[case] input: &str, #[case] expected: Option<i128>) {
297 assert_eq!(i128::parse_path_variable(input), expected);
298 }
299
300 #[test]
301 fn test_isize() {
302 assert_eq!(isize::parse_path_variable("42"), Some(42_isize));
303 assert_eq!(isize::parse_path_variable("-42"), Some(-42_isize));
304 }
305
306 #[rstest]
307 #[case("5.5", Some(5.5f32))]
308 #[case("-5.5", Some(-5.5f32))]
309 #[case("not_a_float", None)]
310 fn test_f32(#[case] input: &str, #[case] expected: Option<f32>) {
311 assert_eq!(f32::parse_path_variable(input), expected);
312 }
313
314 #[rstest]
315 #[case("5.5", Some(5.5))]
316 #[case("-5.5", Some(-5.5))]
317 #[case("not_a_float", None)]
318 fn test_f64(#[case] input: &str, #[case] expected: Option<f64>) {
319 assert_eq!(f64::parse_path_variable(input), expected);
320 }
321
322 #[test]
323 fn test_bytes() {
324 assert_eq!(
325 <&[u8]>::parse_path_variable("test"),
326 Some(b"test".as_slice())
327 );
328 }
329
330 #[test]
331 fn test_str() {
332 assert_eq!(<&str>::parse_path_variable("test"), Some("test"));
333 }
334
335 #[test]
336 fn test_string() {
337 assert_eq!(String::parse_path_variable("test"), Some("test".to_owned()));
338 }
339}