1mod asynchronous;
4mod content_type;
5mod endpoint;
6mod header;
7mod request_target;
8mod response;
9
10pub use asynchronous::AsyncTransport;
11pub use content_type::{
12 ContentType, ContentTypeError, MAX_CONTENT_TYPE_BYTES, MediaType, ResponseContentType,
13};
14pub use endpoint::{
15 AcknowledgedCustomEndpoint, BoundTransport, CustomEndpointAcknowledgement, EndpointIdentity,
16 EndpointIdentityError, EndpointPolicy, EndpointPolicyError, EndpointPolicyKind, EndpointScheme,
17 MAX_ENDPOINT_BASE_PATH_BYTES, MAX_ENDPOINT_HOST_BYTES, MAX_ENDPOINT_REGION_BYTES,
18 MAX_OFFICIAL_ENDPOINTS, RegionEndpoint,
19};
20pub use header::{
21 HeaderError, HeaderName, HeaderSensitivity, HeaderValue, MAX_HEADER_NAME_BYTES,
22 MAX_HEADER_VALUE_BYTES, MAX_REQUEST_HEADER_BYTES, MAX_REQUEST_HEADERS,
23 MAX_RESPONSE_HEADER_BYTES, MAX_RESPONSE_HEADERS, RequestHeader, RequestHeaders, ResponseHeader,
24 ResponseHeaders,
25};
26pub use request_target::{
27 CanonicalQuery, FormQuery, MAX_REQUEST_TARGET_BYTES, QueryPair, QueryPairs, RequestPath,
28 RequestPathError, RequestQuery, RequestTarget, RequestTargetError, StructuredQueryError,
29};
30pub use response::{
31 ResponseBuffer, ResponseMetadata, ResponseWriter, ResponseWriterError, TransportResponse,
32};
33
34use core::fmt;
35
36use crate::Method;
37
38pub trait ResponseStorageSanitizer {
47 fn sanitize_response_storage(&self, response_storage: &mut [u8]);
49}
50
51#[derive(Clone, Copy)]
53pub struct TransportRequest<'a> {
54 method: Method,
55 target: RequestTarget<'a>,
56 body: &'a [u8],
57 headers: RequestHeaders<'a>,
58}
59
60impl<'a> TransportRequest<'a> {
61 #[must_use]
63 pub const fn new(method: Method, target: RequestTarget<'a>) -> Self {
64 Self {
65 method,
66 target,
67 body: &[],
68 headers: RequestHeaders::EMPTY,
69 }
70 }
71
72 #[must_use]
74 pub const fn with_body(mut self, body: &'a [u8]) -> Self {
75 self.body = body;
76 self
77 }
78
79 #[must_use]
81 pub const fn with_headers(mut self, headers: RequestHeaders<'a>) -> Self {
82 self.headers = headers;
83 self
84 }
85
86 #[must_use]
88 pub const fn method(self) -> Method {
89 self.method
90 }
91
92 #[must_use]
94 pub const fn target(self) -> RequestTarget<'a> {
95 self.target
96 }
97
98 #[must_use]
100 pub const fn body(self) -> &'a [u8] {
101 self.body
102 }
103
104 #[must_use]
106 pub const fn headers(self) -> RequestHeaders<'a> {
107 self.headers
108 }
109}
110
111impl fmt::Debug for TransportRequest<'_> {
112 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
113 formatter
114 .debug_struct("TransportRequest")
115 .field("method", &self.method)
116 .field("target", &self.target)
117 .field("body", &"[redacted]")
118 .field("headers", &self.headers)
119 .finish()
120 }
121}
122
123#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
125pub struct StatusCode(u16);
126
127impl StatusCode {
128 pub const OK: Self = Self(200);
130 pub const CREATED: Self = Self(201);
132 pub const ACCEPTED: Self = Self(202);
134 pub const NO_CONTENT: Self = Self(204);
136 pub const TOO_MANY_REQUESTS: Self = Self(429);
138
139 #[must_use]
141 pub const fn new(value: u16) -> Option<Self> {
142 if value < 100 || value > 599 {
143 return None;
144 }
145 Some(Self(value))
146 }
147
148 #[must_use]
150 pub const fn get(self) -> u16 {
151 self.0
152 }
153
154 #[must_use]
156 pub const fn is_success(self) -> bool {
157 self.0 >= 200 && self.0 <= 299
158 }
159
160 #[must_use]
162 pub const fn is_error(self) -> bool {
163 self.0 >= 400
164 }
165}
166
167pub trait BlockingTransport {
176 type Error;
178
179 fn send(
181 &self,
182 request: TransportRequest<'_>,
183 response: &mut ResponseWriter<'_>,
184 ) -> Result<(), Self::Error>;
185}
186
187#[cfg(test)]
188mod tests;