use core::fmt;
use crate::operation::{ExecutionPermitError, ResponsePolicyError};
use crate::transport::{EndpointIdentityError, ResponseWriterError};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PreparedRequestPolicyError {
MissingRequestIdHeader,
ReadOnlyMethodMismatch,
}
impl fmt::Display for PreparedRequestPolicyError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(match self {
Self::MissingRequestIdHeader => {
"prepared request ID policy requires raw x-request-id admission"
}
Self::ReadOnlyMethodMismatch => "read-only operation metadata requires GET or HEAD",
})
}
}
impl core::error::Error for PreparedRequestPolicyError {}
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum PreparedExecutionError<E> {
AuthorizationRequired,
AuthorizationInvalid(ExecutionPermitError),
EndpointIdentity(EndpointIdentityError),
EndpointMismatch,
Transport(E),
ResponseWriter(ResponseWriterError),
ResponsePolicy(ResponsePolicyError),
}
impl<E> fmt::Debug for PreparedExecutionError<E> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::AuthorizationRequired => formatter.write_str("AuthorizationRequired"),
Self::AuthorizationInvalid(error) => formatter
.debug_tuple("AuthorizationInvalid")
.field(error)
.finish(),
Self::EndpointIdentity(error) => formatter
.debug_tuple("EndpointIdentity")
.field(error)
.finish(),
Self::EndpointMismatch => formatter.write_str("EndpointMismatch"),
Self::Transport(_) => formatter.write_str("Transport([redacted])"),
Self::ResponseWriter(error) => formatter
.debug_tuple("ResponseWriter")
.field(error)
.finish(),
Self::ResponsePolicy(error) => formatter
.debug_tuple("ResponsePolicy")
.field(error)
.finish(),
}
}
}
impl<E> fmt::Display for PreparedExecutionError<E> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(match self {
Self::AuthorizationRequired => "state-changing request requires execution authority",
Self::AuthorizationInvalid(_) => "execution authority is no longer valid",
Self::EndpointIdentity(_) => "transport endpoint identity is invalid",
Self::EndpointMismatch => "transport endpoint differs from prepared service",
Self::Transport(_) => "prepared request transport failed",
Self::ResponseWriter(_) => "prepared response transaction failed",
Self::ResponsePolicy(_) => "prepared response policy failed",
})
}
}
impl<E> core::error::Error for PreparedExecutionError<E> {}
impl<E: crate::transport::DeliveryClassified> crate::transport::DeliveryClassified
for PreparedExecutionError<E>
{
fn delivery_phase(&self) -> crate::transport::DeliveryPhase {
use crate::transport::DeliveryPhase;
match self {
Self::AuthorizationRequired
| Self::AuthorizationInvalid(_)
| Self::EndpointIdentity(_)
| Self::EndpointMismatch => DeliveryPhase::NotSent,
Self::Transport(error) => error.delivery_phase(),
Self::ResponseWriter(_) => DeliveryPhase::PossiblySent,
Self::ResponsePolicy(_) => DeliveryPhase::ResponseStarted,
}
}
}
pub(super) enum EndpointCheckError {
Invalid(EndpointIdentityError),
Mismatch,
}
pub(super) fn map_endpoint_error<E>(error: EndpointCheckError) -> PreparedExecutionError<E> {
match error {
EndpointCheckError::Invalid(error) => PreparedExecutionError::EndpointIdentity(error),
EndpointCheckError::Mismatch => PreparedExecutionError::EndpointMismatch,
}
}