rama_http_types/response/mod.rs
1//! Types and traits for generating responses.
2//!
3//! See [`crate::response`] for more details.
4
5use crate::Body;
6
7mod append_headers;
8mod headers;
9mod into_response;
10mod into_response_parts;
11
12#[doc(inline)]
13pub use self::{
14 append_headers::AppendHeaders,
15 headers::Headers,
16 into_response::{IntoResponse, StaticResponseFactory},
17 into_response_parts::{IntoResponseParts, ResponseParts, TryIntoHeaderError},
18};
19
20mod html;
21#[doc(inline)]
22pub use html::Html;
23
24mod json;
25#[doc(inline)]
26pub use json::Json;
27
28mod csv;
29#[doc(inline)]
30pub use csv::Csv;
31
32mod form;
33#[doc(inline)]
34pub use form::Form;
35
36mod redirect;
37#[doc(inline)]
38pub use redirect::Redirect;
39
40/// Type alias for [`http::Response`] whose body type defaults to [`Body`], the most common body
41/// type used with rama.
42pub type Response<T = Body> = http::Response<T>;
43
44/// An [`IntoResponse`]-based result type that uses [`ErrorResponse`] as the error type.
45///
46/// All types which implement [`IntoResponse`] can be converted to an [`ErrorResponse`]. This makes
47/// it useful as a general purpose error type for functions which combine multiple distinct error
48/// types that all implement [`IntoResponse`].
49///
50/// # Example
51///
52/// ```
53/// use rama_http_types::{
54/// response::{IntoResponse, Response},
55/// StatusCode,
56/// };
57///
58/// // two fallible functions with different error types
59/// fn try_something() -> Result<(), ErrorA> {
60/// // ...
61/// # unimplemented!()
62/// }
63///
64/// fn try_something_else() -> Result<(), ErrorB> {
65/// // ...
66/// # unimplemented!()
67/// }
68///
69/// // each error type implements `IntoResponse`
70/// struct ErrorA;
71///
72/// impl IntoResponse for ErrorA {
73/// fn into_response(self) -> Response {
74/// // ...
75/// # unimplemented!()
76/// }
77/// }
78///
79/// enum ErrorB {
80/// SomethingWentWrong,
81/// }
82///
83/// impl IntoResponse for ErrorB {
84/// fn into_response(self) -> Response {
85/// // ...
86/// # unimplemented!()
87/// }
88/// }
89///
90/// // we can combine them using `rama_http::response::Result` and still use `?`
91/// async fn handler() -> rama_http_types::response::Result<&'static str> {
92/// // the errors are automatically converted to `ErrorResponse`
93/// try_something()?;
94/// try_something_else()?;
95///
96/// Ok("it worked!")
97/// }
98/// ```
99///
100/// # As a replacement for `std::result::Result`
101///
102/// Since `rama_http::response::Result` has a default error type you only have to specify the `Ok` type:
103///
104/// ```
105/// use rama_http_types::{
106/// response::{IntoResponse, Response, Result},
107/// StatusCode,
108/// };
109///
110/// // `Result<T>` automatically uses `ErrorResponse` as the error type.
111/// async fn handler() -> Result<&'static str> {
112/// try_something()?;
113///
114/// Ok("it worked!")
115/// }
116///
117/// // You can still specify the error even if you've imported `rama_http::response::Result`
118/// fn try_something() -> Result<(), StatusCode> {
119/// // ...
120/// # unimplemented!()
121/// }
122/// ```
123pub type Result<T, E = ErrorResponse> = std::result::Result<T, E>;
124
125impl<T> IntoResponse for Result<T>
126where
127 T: IntoResponse,
128{
129 fn into_response(self) -> Response {
130 match self {
131 Ok(ok) => ok.into_response(),
132 Err(err) => err.0,
133 }
134 }
135}
136
137/// An [`IntoResponse`]-based error type
138///
139/// See [`Result`] for more details.
140#[derive(Debug)]
141pub struct ErrorResponse(Response);
142
143impl<T> From<T> for ErrorResponse
144where
145 T: IntoResponse,
146{
147 fn from(value: T) -> Self {
148 Self(value.into_response())
149 }
150}