Skip to main content

server_fn/response/
mod.rs

1/// Response types for Actix.
2#[cfg(feature = "actix-no-default")]
3pub mod actix;
4/// Response types for the browser.
5#[cfg(feature = "browser")]
6pub mod browser;
7#[cfg(feature = "generic")]
8pub mod generic;
9/// Response types for Axum.
10#[cfg(feature = "axum-no-default")]
11pub mod http;
12/// Response types for [`reqwest`].
13#[cfg(feature = "reqwest")]
14pub mod reqwest;
15
16use bytes::Bytes;
17use futures::Stream;
18use std::future::Future;
19
20/// Represents the response as created by the server;
21pub trait TryRes<E>
22where
23    Self: Sized,
24{
25    /// Attempts to convert a UTF-8 string into an HTTP response.
26    fn try_from_string(content_type: &str, data: String) -> Result<Self, E>;
27
28    /// Attempts to convert a binary blob represented as bytes into an HTTP response.
29    fn try_from_bytes(content_type: &str, data: Bytes) -> Result<Self, E>;
30
31    /// Attempts to convert a stream of bytes into an HTTP response.
32    fn try_from_stream(
33        content_type: &str,
34        data: impl Stream<Item = Result<Bytes, Bytes>> + Send + 'static,
35    ) -> Result<Self, E>;
36}
37
38/// Represents the response as created by the server;
39pub trait Res {
40    /// Converts an error into a response, with a `500` status code and the error as its body.
41    fn error_response(path: &str, err: Bytes) -> Self;
42    /// Set the `Content-Type` header for the response.
43    fn content_type(&mut self, #[allow(unused_variables)] content_type: &str) {
44        // TODO 0.9: remove this method and default implementation. It is only included here
45        //  to allow setting the `Content-Type` header for error responses without requiring a
46        //  semver-incompatible change.
47    }
48    /// Redirect the response by setting a 302 code and Location header.
49    fn redirect(&mut self, path: &str);
50}
51
52/// Represents the response as received by the client.
53pub trait ClientRes<E> {
54    /// Attempts to extract a UTF-8 string from an HTTP response.
55    fn try_into_string(self) -> impl Future<Output = Result<String, E>> + Send;
56
57    /// Attempts to extract a binary blob from an HTTP response.
58    fn try_into_bytes(self) -> impl Future<Output = Result<Bytes, E>> + Send;
59
60    /// Attempts to extract a binary stream from an HTTP response.
61    fn try_into_stream(
62        self,
63    ) -> Result<
64        impl Stream<Item = Result<Bytes, Bytes>> + Send + Sync + 'static,
65        E,
66    >;
67
68    /// HTTP status code of the response.
69    fn status(&self) -> u16;
70
71    /// Status text for the status code.
72    fn status_text(&self) -> String;
73
74    /// The `Location` header or (if none is set), the URL of the response.
75    fn location(&self) -> String;
76
77    /// Whether the response has the [`REDIRECT_HEADER`](crate::redirect::REDIRECT_HEADER) set.
78    fn has_redirect(&self) -> bool;
79}
80
81/// A mocked response type that can be used in place of the actual server response,
82/// when compiling for the browser.
83///
84/// ## Panics
85/// This always panics if its methods are called. It is used solely to stub out the
86/// server response type when compiling for the client.
87pub struct BrowserMockRes;
88
89impl<E> TryRes<E> for BrowserMockRes {
90    fn try_from_string(_content_type: &str, _data: String) -> Result<Self, E> {
91        unreachable!()
92    }
93
94    fn try_from_bytes(_content_type: &str, _data: Bytes) -> Result<Self, E> {
95        unreachable!()
96    }
97
98    fn try_from_stream(
99        _content_type: &str,
100        _data: impl Stream<Item = Result<Bytes, Bytes>>,
101    ) -> Result<Self, E> {
102        unreachable!()
103    }
104}
105
106impl Res for BrowserMockRes {
107    fn error_response(_path: &str, _err: Bytes) -> Self {
108        unreachable!()
109    }
110
111    fn content_type(&mut self, _content_type: &str) {
112        unreachable!()
113    }
114
115    fn redirect(&mut self, _path: &str) {
116        unreachable!()
117    }
118}