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