#[derive(Debug)]
pub enum AttachError {
Control(CpError),
Rendezvous(crate::rendezvous::error::RendezvousError),
}
impl From<CpError> for AttachError {
fn from(err: CpError) -> Self {
Self::Control(err)
}
}
impl From<crate::rendezvous::error::RendezvousError> for AttachError {
fn from(err: crate::rendezvous::error::RendezvousError) -> Self {
Self::Rendezvous(err)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CpError {
Topology(TopologyError),
Abort(AbortError),
StateSnapshot(StateSnapshotError),
StateRestore(StateRestoreError),
TxCommit(TxCommitError),
TxAbort(TxAbortError),
Delegation(DelegationError),
RendezvousMismatch { expected: u16, actual: u16 },
ReplayDetected { operation: u8, nonce: u32 },
GenerationViolation { expected: u16, actual: u16 },
ResourceExhausted,
Authorisation { operation: u8 },
UnsupportedEffect(u8),
LabelOutOfUniverse { max: u8, actual: u8 },
PolicyAbort { reason: u16 },
ResourceMismatch { expected: u8, actual: u8 },
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TopologyError {
InvalidSession,
InvalidLane,
InvalidState,
GenerationMismatch,
AckTimeout,
CommitFailed,
LaneOutOfRange,
LaneMismatch,
InProgress,
NoPending,
StaleGeneration,
GenerationOverflow,
InvalidInitial,
RendezvousIdMismatch,
SeqnoMismatch,
PendingTableFull,
}
impl From<crate::rendezvous::error::TopologyError> for TopologyError {
fn from(err: crate::rendezvous::error::TopologyError) -> Self {
match err {
crate::rendezvous::error::TopologyError::LaneOutOfRange { .. } => {
TopologyError::LaneOutOfRange
}
crate::rendezvous::error::TopologyError::UnknownSession { .. } => {
TopologyError::InvalidSession
}
crate::rendezvous::error::TopologyError::LaneMismatch { .. } => {
TopologyError::LaneMismatch
}
crate::rendezvous::error::TopologyError::InProgress { .. } => TopologyError::InProgress,
crate::rendezvous::error::TopologyError::NoPending { .. } => TopologyError::NoPending,
crate::rendezvous::error::TopologyError::StaleGeneration { .. } => {
TopologyError::StaleGeneration
}
crate::rendezvous::error::TopologyError::GenerationOverflow { .. } => {
TopologyError::GenerationOverflow
}
crate::rendezvous::error::TopologyError::InvalidInitial { .. } => {
TopologyError::InvalidInitial
}
crate::rendezvous::error::TopologyError::RemoteRendezvousMismatch { .. }
| crate::rendezvous::error::TopologyError::RendezvousIdMismatch { .. } => {
TopologyError::RendezvousIdMismatch
}
crate::rendezvous::error::TopologyError::SeqnoMismatch { .. } => {
TopologyError::SeqnoMismatch
}
crate::rendezvous::error::TopologyError::PendingTableFull => {
TopologyError::PendingTableFull
}
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum AbortError {
SessionNotFound,
GenerationMismatch,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum StateSnapshotError {
SessionNotFound,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum StateRestoreError {
SessionNotFound,
EpochNotFound,
EpochMismatch,
AlreadyFinalized,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TxCommitError {
SessionNotFound,
NoStateSnapshot,
AlreadyFinalized,
GenerationMismatch,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TxAbortError {
SessionNotFound,
NoStateSnapshot,
AlreadyFinalized,
GenerationMismatch,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DelegationError {
InvalidToken,
Exhausted,
ShotMismatch,
}
impl core::fmt::Display for CpError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Topology(e) => write!(f, "Topology error: {:?}", e),
Self::Abort(e) => write!(f, "Abort error: {:?}", e),
Self::StateSnapshot(e) => write!(f, "StateSnapshot error: {:?}", e),
Self::StateRestore(e) => write!(f, "StateRestore error: {:?}", e),
Self::TxCommit(e) => write!(f, "TxCommit error: {:?}", e),
Self::TxAbort(e) => write!(f, "TxAbort error: {:?}", e),
Self::Delegation(e) => write!(f, "Delegation error: {:?}", e),
Self::RendezvousMismatch { expected, actual } => {
write!(
f,
"Rendezvous ID mismatch: expected {}, got {}",
expected, actual
)
}
Self::ReplayDetected { operation, nonce } => {
write!(
f,
"Replay detected: operation {}, nonce {}",
operation, nonce
)
}
Self::GenerationViolation { expected, actual } => {
write!(
f,
"Generation ordering violation: expected {}, got {}",
expected, actual
)
}
Self::ResourceExhausted => write!(f, "Resource exhausted"),
Self::Authorisation { operation } => {
write!(f, "Operation not authorised: {}", operation)
}
Self::UnsupportedEffect(op) => write!(f, "Unsupported effect: {}", op),
Self::LabelOutOfUniverse { max, actual } => write!(
f,
"Program label {} exceeds rendezvous label universe {}",
actual, max
),
Self::PolicyAbort { reason } => write!(f, "Policy abort requested (reason {})", reason),
Self::ResourceMismatch { expected, actual } => {
write!(
f,
"Resource kind mismatch: expected tag {}, got {}",
expected, actual
)
}
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for CpError {}
impl From<TopologyError> for CpError {
fn from(e: TopologyError) -> Self {
Self::Topology(e)
}
}
impl From<AbortError> for CpError {
fn from(e: AbortError) -> Self {
Self::Abort(e)
}
}
impl From<StateSnapshotError> for CpError {
fn from(e: StateSnapshotError) -> Self {
Self::StateSnapshot(e)
}
}
impl From<StateRestoreError> for CpError {
fn from(e: StateRestoreError) -> Self {
Self::StateRestore(e)
}
}
impl From<TxCommitError> for CpError {
fn from(e: TxCommitError) -> Self {
Self::TxCommit(e)
}
}
impl From<TxAbortError> for CpError {
fn from(e: TxAbortError) -> Self {
Self::TxAbort(e)
}
}
impl From<DelegationError> for CpError {
fn from(e: DelegationError) -> Self {
Self::Delegation(e)
}
}
#[cfg(all(test, feature = "std"))]
mod tests {
use super::*;
#[test]
fn test_error_conversions() {
let topology_err: CpError = TopologyError::InvalidSession.into();
assert!(matches!(topology_err, CpError::Topology(_)));
let abort_err: CpError = AbortError::SessionNotFound.into();
assert!(matches!(abort_err, CpError::Abort(_)));
}
#[test]
fn test_error_display() {
let err = CpError::RendezvousMismatch {
expected: 1,
actual: 2,
};
let s = format!("{}", err);
assert!(s.contains("expected 1"));
assert!(s.contains("got 2"));
}
}