mod asynchronous;
mod cleanup;
mod content_type;
mod endpoint;
mod header;
mod request_target;
mod response;
mod retained;
mod workspace;
pub use asynchronous::AsyncTransport;
pub use cleanup::ResponseStorageSanitizer;
pub use content_type::{
ContentType, ContentTypeError, MAX_CONTENT_TYPE_BYTES, MediaType, ResponseContentType,
};
pub use endpoint::{
AcknowledgedCustomEndpoint, BoundTransport, CustomEndpointAcknowledgement, EndpointIdentity,
EndpointIdentityError, EndpointPolicy, EndpointPolicyError, EndpointPolicyKind, EndpointScheme,
MAX_ENDPOINT_BASE_PATH_BYTES, MAX_ENDPOINT_HOST_BYTES, MAX_ENDPOINT_REGION_BYTES,
MAX_OFFICIAL_ENDPOINTS, RegionEndpoint,
};
pub use header::{
HeaderError, HeaderName, HeaderSensitivity, HeaderValue, MAX_HEADER_NAME_BYTES,
MAX_HEADER_VALUE_BYTES, MAX_REQUEST_HEADER_BYTES, MAX_REQUEST_HEADERS,
MAX_RESPONSE_HEADER_BYTES, MAX_RESPONSE_HEADERS, RequestHeader, RequestHeaders, ResponseHeader,
ResponseHeaders,
};
pub use request_target::{
CanonicalQuery, FormQuery, MAX_REQUEST_TARGET_BYTES, QueryPair, QueryPairs, RequestPath,
RequestPathError, RequestQuery, RequestTarget, RequestTargetError, StructuredQueryError,
};
pub use response::{
ResponseBuffer, ResponseMetadata, ResponseWriter, ResponseWriterError, TransportResponse,
};
pub use retained::{MAX_REQUEST_ID_BYTES, RetainedMetadataError, RetainedResponseMetadata};
pub use workspace::{
RESPONSE_CURSOR_SCRATCH_BYTES, RESPONSE_DECODER_SCRATCH_BYTES,
RESPONSE_PROVIDER_LINK_SCRATCH_BYTES, ResponseDecodeWorkspace,
};
use core::fmt;
use crate::Method;
#[derive(Clone, Copy)]
pub struct TransportRequest<'a> {
method: Method,
target: RequestTarget<'a>,
body: &'a [u8],
headers: RequestHeaders<'a>,
}
impl<'a> TransportRequest<'a> {
#[must_use]
pub const fn new(method: Method, target: RequestTarget<'a>) -> Self {
Self {
method,
target,
body: &[],
headers: RequestHeaders::EMPTY,
}
}
#[must_use]
pub const fn with_body(mut self, body: &'a [u8]) -> Self {
self.body = body;
self
}
#[must_use]
pub const fn with_headers(mut self, headers: RequestHeaders<'a>) -> Self {
self.headers = headers;
self
}
#[must_use]
pub const fn method(self) -> Method {
self.method
}
#[must_use]
pub const fn target(self) -> RequestTarget<'a> {
self.target
}
#[must_use]
pub const fn body(self) -> &'a [u8] {
self.body
}
#[must_use]
pub const fn headers(self) -> RequestHeaders<'a> {
self.headers
}
}
impl fmt::Debug for TransportRequest<'_> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("TransportRequest")
.field("method", &self.method)
.field("target", &self.target)
.field("body", &"[redacted]")
.field("headers", &self.headers)
.finish()
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct StatusCode(u16);
impl StatusCode {
pub const OK: Self = Self(200);
pub const CREATED: Self = Self(201);
pub const ACCEPTED: Self = Self(202);
pub const NO_CONTENT: Self = Self(204);
pub const TOO_MANY_REQUESTS: Self = Self(429);
#[must_use]
pub const fn new(value: u16) -> Option<Self> {
if value < 100 || value > 599 {
return None;
}
Some(Self(value))
}
#[must_use]
pub const fn get(self) -> u16 {
self.0
}
#[must_use]
pub const fn is_success(self) -> bool {
self.0 >= 200 && self.0 <= 299
}
#[must_use]
pub const fn is_error(self) -> bool {
self.0 >= 400
}
}
pub trait BlockingTransport {
type Error;
fn send(
&self,
request: TransportRequest<'_>,
response: &mut ResponseWriter<'_>,
) -> Result<(), Self::Error>;
}
#[cfg(test)]
mod tests;