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}