use super::{ChoreoResult, ChoreographyError};
impl ChoreographyError {
#[must_use]
pub fn with_protocol_context(
self,
protocol: &'static str,
role: &'static str,
phase: &'static str,
) -> Self {
ChoreographyError::ProtocolContext {
protocol,
role,
phase,
inner: Box::new(self),
}
}
#[must_use]
pub fn with_role_context(self, role: &'static str, index: Option<u32>) -> Self {
ChoreographyError::RoleContext {
role,
index,
inner: Box::new(self),
}
}
#[must_use]
pub fn with_message_context(
self,
operation: &'static str,
message_type: &'static str,
direction: &'static str,
other_role: &'static str,
) -> Self {
ChoreographyError::MessageContext {
operation,
message_type,
direction,
other_role,
inner: Box::new(self),
}
}
#[must_use]
pub fn with_context(self, context: impl Into<String>) -> Self {
ChoreographyError::WithContext {
context: context.into(),
inner: Box::new(self),
}
}
#[must_use]
pub fn root_cause(&self) -> &ChoreographyError {
match self {
ChoreographyError::ProtocolContext { inner, .. }
| ChoreographyError::RoleContext { inner, .. }
| ChoreographyError::MessageContext { inner, .. }
| ChoreographyError::WithContext { inner, .. } => inner.root_cause(),
_ => self,
}
}
#[must_use]
pub fn is_timeout(&self) -> bool {
matches!(self.root_cause(), ChoreographyError::Timeout(_))
}
#[must_use]
pub fn is_transport(&self) -> bool {
matches!(
self.root_cause(),
ChoreographyError::Transport(_)
| ChoreographyError::ChannelSendFailed { .. }
| ChoreographyError::ChannelClosed { .. }
| ChoreographyError::NoPeerChannel { .. }
)
}
#[must_use]
pub fn is_protocol_violation(&self) -> bool {
matches!(self.root_cause(), ChoreographyError::ProtocolViolation(_))
}
#[must_use]
pub fn is_serialization(&self) -> bool {
matches!(
self.root_cause(),
ChoreographyError::Serialization(_)
| ChoreographyError::LabelSerializationFailed { .. }
| ChoreographyError::MessageSerializationFailed { .. }
)
}
}
pub trait ContextExt<T> {
fn with_protocol_context(
self,
protocol: &'static str,
role: &'static str,
phase: &'static str,
) -> ChoreoResult<T>;
fn with_role_context(self, role: &'static str, index: Option<u32>) -> ChoreoResult<T>;
fn with_message_context(
self,
operation: &'static str,
message_type: &'static str,
direction: &'static str,
other_role: &'static str,
) -> ChoreoResult<T>;
fn with_context(self, context: impl Into<String>) -> ChoreoResult<T>;
}
impl<T> ContextExt<T> for ChoreoResult<T> {
fn with_protocol_context(
self,
protocol: &'static str,
role: &'static str,
phase: &'static str,
) -> ChoreoResult<T> {
self.map_err(|e| e.with_protocol_context(protocol, role, phase))
}
fn with_role_context(self, role: &'static str, index: Option<u32>) -> ChoreoResult<T> {
self.map_err(|e| e.with_role_context(role, index))
}
fn with_message_context(
self,
operation: &'static str,
message_type: &'static str,
direction: &'static str,
other_role: &'static str,
) -> ChoreoResult<T> {
self.map_err(|e| e.with_message_context(operation, message_type, direction, other_role))
}
fn with_context(self, context: impl Into<String>) -> ChoreoResult<T> {
self.map_err(|e| e.with_context(context))
}
}