1mod redirects;
2mod uri;
3
4pub use self::redirects::{Redirect, RedirectParseError, RedirectTo, StatusCode};
5pub use self::uri::{RelativeRef, Uri};
6
7use serde::{Deserialize, Serialize};
8
9mod http_serde {
10 use serde::{Deserialize, Deserializer, Serialize, Serializer};
11
12 pub mod status_code {
13 use super::*;
14 use http::StatusCode;
15 use serde::de::Error;
16
17 pub fn serialize<S: Serializer>(
18 value: &StatusCode,
19 serializer: S,
20 ) -> Result<S::Ok, S::Error> {
21 value.as_u16().serialize(serializer)
22 }
23
24 pub fn deserialize<'de, D: Deserializer<'de>>(
25 deserializer: D,
26 ) -> Result<StatusCode, D::Error> {
27 let code = u16::deserialize(deserializer)?;
28 Ok(StatusCode::from_u16(code).map_err(D::Error::custom)?)
29 }
30 }
31}
32
33#[derive(Deserialize, Serialize, Debug, Clone)]
34pub struct PermaLink {
35 #[serde(with = "crate::http_serde::status_code")]
36 code: StatusCode,
37
38 to: Uri,
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn parse_redirect_to() {
47 assert_eq!(
48 "https://www.example.com".parse::<RedirectTo>().unwrap(),
49 RedirectTo::Uri(Uri::parse("https://www.example.com").unwrap()),
50 );
51 assert_eq!(
52 "https://www.example.com/:splat"
53 .parse::<RedirectTo>()
54 .unwrap(),
55 RedirectTo::Uri(Uri::parse("https://www.example.com/:splat").unwrap()),
56 );
57 assert_eq!("/abc".parse::<RedirectTo>().unwrap().path(), "/abc");
58 assert_eq!(
59 "/abc/:splat".parse::<RedirectTo>().unwrap().path(),
60 "/abc/:splat"
61 );
62 }
63}