sark_core/http/response/
static_response.rs1use http::StatusCode;
2use o3::buffer::{Owned, Shared};
3
4use super::wire_emit::{ContentLength, HeadWrite, PLACEHOLDER_DATE, WireWriter};
5use super::{DEFAULT_HEADER_CAPACITY, HeadInner, Headers};
6
7#[derive(Clone, Debug)]
12pub struct StaticResponseInner<'req, const N: usize = DEFAULT_HEADER_CAPACITY> {
13 status: StatusCode,
14 head: HeadInner<'req, N>,
15 body: &'static [u8],
16}
17
18impl<'req, const N: usize> StaticResponseInner<'req, N> {
19 pub fn direct(
20 status: StatusCode,
21 static_headers: &'static [u8],
22 headers: Headers<'req, N>,
23 body: &'static [u8],
24 ) -> Self {
25 Self {
26 status,
27 head: HeadInner::new(static_headers, headers),
28 body,
29 }
30 }
31
32 pub fn status(&self) -> StatusCode {
33 self.status
34 }
35
36 pub fn body_ref(&self) -> &'static [u8] {
37 self.body
38 }
39
40 pub fn wire_headers(&self) -> Shared {
41 let mut out = Owned::with_capacity(self.head.wire_len());
42 self.head.write_into_owned(&mut out);
43 out.freeze()
44 }
45
46 fn head_write(&self) -> HeadWrite<'_, HeadInner<'req, N>, ContentLength> {
47 HeadWrite {
48 status_str: self.status.as_str().as_bytes(),
49 reason: self
50 .status
51 .canonical_reason()
52 .map(str::as_bytes)
53 .unwrap_or(b""),
54 headers: &self.head,
55 framing: ContentLength(self.body.len()),
56 }
57 }
58
59 pub fn write_into_slice(&self, out: &mut [u8], date: &[u8; 29]) -> Option<usize> {
60 let head = self.head_write();
61 let total = head.wire_len().checked_add(self.body.len())?;
62 if out.len() < total {
63 return None;
64 }
65 let written = head.write(out, date);
66 let mut out = WireWriter::at(out, written.len);
67 out.put(self.body);
68 Some(out.len())
69 }
70
71 pub fn write_head_only(
72 &self,
73 out: &mut [u8],
74 date: &[u8; 29],
75 ) -> Option<(usize, &'static [u8])> {
76 let head = self.head_write();
77 if out.len() < head.wire_len() {
78 return None;
79 }
80 let written = head.write(out, date);
81 Some((written.len, self.body))
82 }
83
84 pub fn write_head_split(self, out: &mut [u8], date: &[u8; 29]) -> Option<(usize, Shared)> {
85 let (off, body) = self.write_head_only(out, date)?;
86 Some((off, Shared::from_static(body)))
87 }
88
89 pub fn preserialize_static(&self) -> (Vec<u8>, usize, &'static [u8]) {
90 let head = self.head_write();
91 let mut out = vec![0u8; head.wire_len()];
92 let written = head.write(&mut out, PLACEHOLDER_DATE);
93 (out, written.date_offset, self.body)
94 }
95}