sark_core/http/response/direct/
plan.rs1use http::StatusCode;
2use o3::buffer::{Borrowed, Bytes, Owned, Retained, Shared};
3
4use super::super::{HotBodyInner, HotHeadInner, IntoBody, MonoResponseInner};
5use super::head::HeadInner;
6use super::headers::{HeaderAssert, HeaderNameToken, HeaderStaticValueToken, HeadersInner};
7use super::value::{InlineHeaderValue, TextSpec};
8
9#[derive(Clone, Debug)]
10pub struct ResponsePlanInner<'req> {
11 pub(in crate::http::response) status: StatusCode,
12 pub(in crate::http::response) head: HeadInner<'req>,
13}
14
15pub type ResponsePlan = ResponsePlanInner<'static>;
16
17impl<'req> ResponsePlanInner<'req> {
18 pub fn with_capacity(status: StatusCode) -> Self {
19 Self {
20 status,
21 head: HeadInner::new(b"", HeadersInner::new()),
22 }
23 }
24
25 pub fn from_static(status: StatusCode, static_headers: &'static [u8]) -> Self {
26 Self {
27 status,
28 head: HeadInner::new(static_headers, HeadersInner::new()),
29 }
30 }
31
32 pub fn new(status: StatusCode) -> Self {
33 Self::with_capacity(status)
34 }
35
36 pub fn ok() -> Self {
37 Self::new(StatusCode::OK)
38 }
39
40 pub fn not_found() -> Self {
41 Self::new(StatusCode::NOT_FOUND)
42 }
43
44 pub fn status(&self) -> StatusCode {
45 self.status
46 }
47
48 pub fn wire_headers(&self) -> Shared {
49 let mut out = Owned::with_capacity(self.head.wire_len());
50 self.head.write_into_owned(&mut out);
51 out.freeze()
52 }
53
54 pub fn push_static(&mut self, name: &'static str, value: &'static str) -> &mut Self {
55 let name = HeaderNameToken::new(name);
56 let value = HeaderStaticValueToken::new(value);
57 self.head.headers_mut().push_static(name, value);
58 self
59 }
60
61 pub fn push(&mut self, name: &'static str, value: &str) -> &mut Self {
62 self.push_str_value(HeaderNameToken::new(name), value)
63 }
64
65 pub fn push_token_static(
66 &mut self,
67 name: HeaderNameToken,
68 value: HeaderStaticValueToken,
69 ) -> &mut Self {
70 self.head.headers_mut().push_static(name, value);
71 self
72 }
73
74 pub fn push_token(&mut self, name: HeaderNameToken, value: &str) -> &mut Self {
75 self.push_str_value(name, value)
76 }
77
78 fn push_str_value(&mut self, name: HeaderNameToken, value: &str) -> &mut Self {
79 HeaderAssert::value(value);
80 if value.len() <= 31 {
81 self.head
82 .headers_mut()
83 .push_inline(name, InlineHeaderValue::new(value.as_bytes()));
84 } else {
85 self.head
86 .headers_mut()
87 .push_shared(name, Shared::copy_from_slice(value.as_bytes()));
88 }
89 self
90 }
91
92 pub fn push_borrowed_token(
93 &mut self,
94 name: HeaderNameToken,
95 value: Bytes<Borrowed<'req>>,
96 ) -> &mut Self {
97 HeaderAssert::value_bytes(value.as_slice());
98 self.head.headers_mut().push_borrowed(name, value);
99 self
100 }
101
102 pub fn push_retained_token(
103 &mut self,
104 name: HeaderNameToken,
105 value: Bytes<Retained>,
106 ) -> &mut Self {
107 HeaderAssert::value_bytes(value.as_slice());
108 self.head.headers_mut().push_retained(name, value);
109 self
110 }
111
112 pub fn respond_mono<B>(self, body: B) -> MonoResponseInner<'req>
113 where
114 B: IntoBody<'req>,
115 {
116 let status = self.status;
117 MonoResponseInner {
118 status,
119 headers: None,
120 head: HotHeadInner::Direct(self.head),
121 body: HotBodyInner::from(body.into_response_body()),
122 }
123 }
124
125 pub fn respond_text<T>(self, body: T) -> MonoResponseInner<'req>
126 where
127 T: TextSpec<'req>,
128 {
129 let status = self.status;
130 MonoResponseInner {
131 status,
132 headers: None,
133 head: HotHeadInner::Direct(self.head),
134 body: HotBodyInner::Text(body.into_hot_text()),
135 }
136 }
137}