Skip to main content

sark_core/http/response/
serve.rs

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