@@ -125,6 +125,7 @@ pub trait ResponseExt: Sized + private::Sealed {
125125 /// * [`crate::reverse_redirect!`] – a more ergonomic way to create
126126 /// redirects to internal views
127127 #[ must_use]
128+ #[ deprecated( since = "0.5.0" , note = "Use Redirect::new() instead" ) ]
128129 fn new_redirect < T : Into < String > > ( location : T ) -> Self ;
129130}
130131
@@ -144,6 +145,58 @@ impl ResponseExt for Response {
144145 }
145146}
146147
148+ /// A redirect response.
149+ ///
150+ /// This type creates an HTTP redirect response with a status code of
151+ /// [`StatusCode::SEE_OTHER`] (303) and a `Location` header set to the
152+ /// specified URL.
153+ ///
154+ /// # Examples
155+ ///
156+ /// ```
157+ /// use cot::response::{IntoResponse, Redirect};
158+ ///
159+ /// let response = Redirect::new("https://example.com");
160+ ///
161+ /// assert_eq!(response.status(), cot::StatusCode::SEE_OTHER);
162+ /// ```
163+ ///
164+ /// # See also
165+ ///
166+ /// * [`crate::reverse_redirect!`] – a more ergonomic way to create redirects to
167+ /// internal views
168+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
169+ pub struct Redirect ;
170+
171+ impl Redirect {
172+ /// Creates a new redirect response to the specified location.
173+ ///
174+ /// The location can be any type that implements `Into<String>`, such as
175+ /// `&str`, `String`, or other string-like types.
176+ ///
177+ /// # Panics
178+ ///
179+ /// Panics if the provided location does not cast into
180+ /// [`http::HeaderValue`].
181+ ///
182+ /// # Examples
183+ ///
184+ /// ```
185+ /// use cot::response::Redirect;
186+ ///
187+ /// let redirect = Redirect::new("/login");
188+ /// ```
189+ #[ must_use]
190+ #[ expect( clippy:: new_ret_no_self) ]
191+ pub fn new < T : Into < String > > ( location : T ) -> Response {
192+ http:: Response :: builder ( )
193+ . status ( StatusCode :: SEE_OTHER )
194+ . header ( http:: header:: LOCATION , location. into ( ) )
195+ . body ( Body :: empty ( ) )
196+ . expect ( RESPONSE_BUILD_FAILURE )
197+ }
198+ }
199+
147200#[ cfg( test) ]
148201mod tests {
149202 use super :: * ;
@@ -179,6 +232,7 @@ mod tests {
179232 }
180233
181234 #[ test]
235+ #[ expect( deprecated) ]
182236 fn response_new_redirect ( ) {
183237 let location = "http://example.com" ;
184238 let response = Response :: new_redirect ( location) ;
0 commit comments