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