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