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}