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