sark_core/http/response/
static_response.rs1use http::StatusCode;
2use o3::buffer::Shared;
3
4use super::wire_emit::{ContentLength, HeadWrite, PLACEHOLDER_DATE, ProvenWireWriter};
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 let mut out = ProvenWireWriter::new(out, total)?;
84 head.emit(&mut out, date);
85 out.put(self.body);
86 Some(out.finish(total))
87 }
88
89 pub fn write_head_only(
90 &self,
91 out: &mut [u8],
92 date: &[u8; 29],
93 ) -> Option<(usize, &'static [u8])> {
94 let head = self.head_write();
95 let head_len = head.wire_len();
96 let mut out = ProvenWireWriter::new(out, head_len)?;
97 head.emit(&mut out, date);
98 Some((out.finish(head_len), self.body))
99 }
100
101 pub fn write_head_split(self, out: &mut [u8], date: &[u8; 29]) -> Option<(usize, Shared)> {
102 let (off, body) = self.write_head_only(out, date)?;
103 Some((off, Shared::from_static(body)))
104 }
105
106 pub fn preserialize_static(&self) -> (Vec<u8>, usize, &'static [u8]) {
107 let head = self.head_write();
108 let head_len = head.wire_len();
109 let mut out = vec![0u8; head_len];
110 let mut writer = ProvenWireWriter::exact(&mut out);
111 let date_offset = head.emit(&mut writer, PLACEHOLDER_DATE);
112 writer.finish(head_len);
113 (out, date_offset, self.body)
114 }
115}