Skip to main content

perma_core/
lib.rs

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}