sark_core/http/response/
static_response.rs1use http::StatusCode;
2use o3::buffer::{Owned, Shared};
3
4use super::wire_emit::{ContentLength, HeadWrite, Out, PLACEHOLDER_DATE};
5use super::{DEFAULT_HEADER_CAPACITY, HeadInner, HeadersInner};
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: HeadersInner<'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 mut off = 0usize;
66 head.write(out, &mut off, date);
67 Out::put(out, &mut off, self.body);
68 Some(off)
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 mut off = 0usize;
81 head.write(out, &mut off, date);
82 Some((off, self.body))
83 }
84
85 pub fn write_head_split(self, out: &mut [u8], date: &[u8; 29]) -> Option<(usize, Shared)> {
86 let (off, body) = self.write_head_only(out, date)?;
87 Some((off, Shared::from_static(body)))
88 }
89
90 pub fn preserialize_static(&self) -> (Vec<u8>, usize, &'static [u8]) {
91 let head = self.head_write();
92 let mut out = vec![0u8; head.wire_len()];
93 let mut off = 0usize;
94 let date_offset = head.write(&mut out, &mut off, PLACEHOLDER_DATE);
95 (out, date_offset, self.body)
96 }
97}