sark_core/http/response/
static_response.rs1use http::StatusCode;
2use o3::buffer::Shared;
3
4use super::wire_emit::{ContentLength, HeadWrite, PLACEHOLDER_DATE, WireWriter};
5use super::{
6 DEFAULT_HEADER_CAPACITY, HeadInner, HeaderTemplate, Headers, StaticHeaderBytes,
7 StaticHeaderFields, StaticHeaders,
8};
9
10#[derive(Clone, Debug)]
15pub struct StaticResponseInner<
16 'req,
17 const N: usize = DEFAULT_HEADER_CAPACITY,
18 S = StaticHeaderBytes,
19> {
20 pub(super) status: StatusCode,
21 pub(super) head: HeadInner<'req, N, S>,
22 pub(super) body: &'static [u8],
23}
24
25impl<'req, const N: usize> StaticResponseInner<'req, N> {
26 pub fn direct(
27 status: StatusCode,
28 static_headers: &'static [u8],
29 headers: Headers<'req, N>,
30 body: &'static [u8],
31 ) -> Self {
32 Self {
33 status,
34 head: HeadInner::new(static_headers, headers),
35 body,
36 }
37 }
38}
39
40impl<'req, const N: usize> StaticResponseInner<'req, N, StaticHeaderFields> {
41 #[doc(hidden)]
42 pub fn structured(
43 status: StatusCode,
44 static_headers: &'static HeaderTemplate,
45 headers: Headers<'req, N>,
46 body: &'static [u8],
47 ) -> Self {
48 Self {
49 status,
50 head: HeadInner::structured(static_headers, headers),
51 body,
52 }
53 }
54}
55
56impl<'req, const N: usize, S> StaticResponseInner<'req, N, S>
57where
58 S: StaticHeaders,
59{
60 pub fn status(&self) -> StatusCode {
61 self.status
62 }
63
64 pub fn body_ref(&self) -> &'static [u8] {
65 self.body
66 }
67
68 pub fn wire_headers(&self) -> Shared {
69 self.head.wire_headers()
70 }
71
72 fn head_write(&self) -> HeadWrite<'_, HeadInner<'req, N, S>, ContentLength> {
73 HeadWrite {
74 status: self.status,
75 headers: &self.head,
76 framing: ContentLength(self.body.len()),
77 }
78 }
79
80 pub fn write_into_slice(&self, out: &mut [u8], date: &[u8; 29]) -> Option<usize> {
81 let head = self.head_write();
82 let total = head.wire_len().checked_add(self.body.len())?;
83 if out.len() < total {
84 return None;
85 }
86 let written = head.write(out, date);
87 let mut out = WireWriter::at(out, written.len);
88 out.put(self.body);
89 Some(out.len())
90 }
91
92 pub fn write_head_only(
93 &self,
94 out: &mut [u8],
95 date: &[u8; 29],
96 ) -> Option<(usize, &'static [u8])> {
97 let head = self.head_write();
98 if out.len() < head.wire_len() {
99 return None;
100 }
101 let written = head.write(out, date);
102 Some((written.len, self.body))
103 }
104
105 pub fn write_head_split(self, out: &mut [u8], date: &[u8; 29]) -> Option<(usize, Shared)> {
106 let (off, body) = self.write_head_only(out, date)?;
107 Some((off, Shared::from_static(body)))
108 }
109
110 pub fn preserialize_static(&self) -> (Vec<u8>, usize, &'static [u8]) {
111 let head = self.head_write();
112 let mut out = vec![0u8; head.wire_len()];
113 let written = head.write(&mut out, PLACEHOLDER_DATE);
114 (out, written.date_offset, self.body)
115 }
116}