volo_http/server/response/
redirect.rs

1use http::{
2    header::{self, HeaderValue},
3    status::StatusCode,
4};
5
6use super::IntoResponse;
7use crate::{body::Body, response::Response};
8
9/// Response with 3XX Status Code and specified `Location`
10pub struct Redirect {
11    status: StatusCode,
12    location: HeaderValue,
13}
14
15impl Redirect {
16    /// Create a new [`Redirect`] with a status code and a target location.
17    ///
18    /// # Panics
19    ///
20    /// If the location is not a valid header value.
21    pub fn with_status_code(status: StatusCode, location: &str) -> Self {
22        debug_assert!(status.is_redirection());
23
24        Self {
25            status,
26            location: HeaderValue::from_str(location)
27                .expect("The target location is not a valid header value"),
28        }
29    }
30
31    /// Create a new [`Redirect`] with [`301 Moved Permanently`][301] status code.
32    ///
33    /// # Panics
34    ///
35    /// If the location is not a valid header value.
36    ///
37    /// [301]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301
38    pub fn moved_permanently(location: &str) -> Self {
39        Self::with_status_code(StatusCode::MOVED_PERMANENTLY, location)
40    }
41
42    /// Create a new [`Redirect`] with [`302 Found`][302] status code.
43    ///
44    /// # Panics
45    ///
46    /// If the location is not a valid header value.
47    ///
48    /// [302]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302
49    pub fn found(location: &str) -> Self {
50        Self::with_status_code(StatusCode::FOUND, location)
51    }
52
53    /// Create a new [`Redirect`] with [`303 Found`][303] status code.
54    ///
55    /// # Panics
56    ///
57    /// If the location is not a valid header value.
58    ///
59    /// [303]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303
60    pub fn see_other(location: &str) -> Self {
61        Self::with_status_code(StatusCode::SEE_OTHER, location)
62    }
63
64    /// Create a new [`Redirect`] with [`307 Temporary Redirect`][307] status code.
65    ///
66    /// # Panics
67    ///
68    /// If the location is not a valid header value.
69    ///
70    /// [307]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307
71    pub fn temporary_redirect(location: &str) -> Self {
72        Self::with_status_code(StatusCode::TEMPORARY_REDIRECT, location)
73    }
74
75    /// Create a new [`Redirect`] with [`308 Permanent Redirect`][308] status code.
76    ///
77    /// # Panics
78    ///
79    /// If the location is not a valid header value.
80    ///
81    /// [308]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308
82    pub fn permanent_redirect(location: &str) -> Self {
83        Self::with_status_code(StatusCode::PERMANENT_REDIRECT, location)
84    }
85}
86
87impl IntoResponse for Redirect {
88    fn into_response(self) -> Response {
89        Response::builder()
90            .status(self.status)
91            .header(header::LOCATION, self.location)
92            .body(Body::default())
93            .expect("infallible")
94    }
95}