Skip to main content

sark_core/http/response/
serve.rs

1use http::StatusCode;
2
3use super::{Chunked, FixedResponseInner, HotBodyInner, HotHeadInner, MonoResponseInner, Response};
4
5#[allow(clippy::large_enum_variant)]
6#[derive(Clone, Debug)]
7pub enum ServeInner<'req> {
8    Chunked(Chunked),
9    Fixed(FixedResponseInner<'req>),
10    Mono(MonoResponseInner<'req>),
11}
12
13pub type Serve = ServeInner<'static>;
14
15impl<'req> ServeInner<'req> {
16    pub fn status(&self) -> StatusCode {
17        match self {
18            Self::Chunked(response) => response.status(),
19            Self::Fixed(response) => response.status(),
20            Self::Mono(response) => response.status(),
21        }
22    }
23}
24
25impl ServeInner<'static> {
26    pub fn into_response(self) -> Response {
27        match self {
28            Self::Chunked(response) => response.into_response(),
29            Self::Fixed(response) => Response::from(response),
30            Self::Mono(response) => Response::from(response),
31        }
32    }
33}
34
35impl From<Response> for ServeInner<'static> {
36    fn from(value: Response) -> Self {
37        if let Some(parts) = value.chunked_parts {
38            return Self::Chunked(Chunked::from_parts(
39                value.status,
40                value.headers,
41                value.wire_headers.freeze(),
42                parts,
43            ));
44        }
45        let headers = if value.headers.is_empty() {
46            None
47        } else {
48            Some(Box::new(value.headers))
49        };
50        Self::Mono(MonoResponseInner {
51            status: value.status,
52            headers,
53            head: HotHeadInner::Wire(value.wire_headers.freeze()),
54            body: HotBodyInner::from(value.body),
55        })
56    }
57}
58
59impl<'req> From<MonoResponseInner<'req>> for ServeInner<'req> {
60    fn from(value: MonoResponseInner<'req>) -> Self {
61        Self::Mono(value)
62    }
63}
64
65impl<'req> From<FixedResponseInner<'req>> for ServeInner<'req> {
66    fn from(value: FixedResponseInner<'req>) -> Self {
67        Self::Fixed(value)
68    }
69}
70
71pub trait IntoServeResponse<'req> {
72    fn into_serve_response(self) -> ServeInner<'req>;
73}
74
75pub trait IntoServeResponseStatic<'req> {
76    fn into_serve_response_static(self) -> ServeInner<'req>;
77}
78
79impl<'req> IntoServeResponse<'req> for ServeInner<'req> {
80    fn into_serve_response(self) -> Self {
81        self
82    }
83}
84
85impl IntoServeResponse<'static> for Response {
86    fn into_serve_response(self) -> ServeInner<'static> {
87        ServeInner::from(self)
88    }
89}
90
91impl<'req> IntoServeResponse<'req> for MonoResponseInner<'req> {
92    fn into_serve_response(self) -> ServeInner<'req> {
93        ServeInner::Mono(self)
94    }
95}
96
97impl<'req> IntoServeResponse<'req> for FixedResponseInner<'req> {
98    fn into_serve_response(self) -> ServeInner<'req> {
99        ServeInner::Fixed(self)
100    }
101}