distributed 4.3.0

CQRS/ES framework for Rust using Plain Old Rust Structs — append-only events, replay, snapshots, outbox, service bus, and pluggable infrastructure
Documentation
use super::*;

#[derive(Debug)]
#[non_exhaustive]
pub enum ProjectionProtocolError {
    Validation(ProjectionProtocolValidationError),
    Repository(RepositoryError),
    Table(TableStoreError),
    InvalidBatch(String),
    ScopeMismatch {
        field: &'static str,
    },
    IncomparableInput,
    InputCorruption,
    MessageIdReuse {
        message_id: String,
    },
    GenerationFenced {
        expected: u64,
        actual: u64,
    },
    PartitionStopped {
        failure_id: String,
    },
    RecordMissing {
        model: String,
    },
    RecordAlreadyExists {
        model: String,
    },
    RecordRevisionConflict {
        model: String,
        expected_incarnation: u64,
        expected_revision: u64,
        actual_incarnation: u64,
        actual_revision: u64,
    },
    RecordTombstoned {
        model: String,
    },
    RecreateRequiresTombstone {
        model: String,
    },
    CausalWriteRequired {
        table: String,
    },
    PositionOverflow {
        domain: &'static str,
    },
}

impl fmt::Display for ProjectionProtocolError {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Validation(error) => write!(formatter, "invalid projection protocol value: {error}"),
            Self::Repository(error) => write!(formatter, "projection repository error: {error}"),
            Self::Table(error) => write!(formatter, "projection table error: {error}"),
            Self::InvalidBatch(message) => write!(formatter, "invalid projection batch: {message}"),
            Self::ScopeMismatch { field } => write!(formatter, "{field} does not match the projection input scope"),
            Self::IncomparableInput => formatter.write_str("projection input is incomparable with the durable checkpoint"),
            Self::InputCorruption => formatter.write_str("the same projection input cursor was reused with different content"),
            Self::MessageIdReuse { message_id } => write!(formatter, "projection message ID `{message_id}` was reused for a different input"),
            Self::GenerationFenced { expected, actual } => write!(formatter, "projection generation {actual} is fenced; active generation is {expected}"),
            Self::PartitionStopped { failure_id } => write!(formatter, "projection partition is stopped by terminal failure `{failure_id}`"),
            Self::RecordMissing { model } => write!(formatter, "projection record `{model}` does not exist"),
            Self::RecordAlreadyExists { model } => write!(formatter, "projection record `{model}` already exists"),
            Self::RecordRevisionConflict { model, expected_incarnation, expected_revision, actual_incarnation, actual_revision } => write!(formatter, "projection record `{model}` expected revision ({expected_incarnation}, {expected_revision}) but found ({actual_incarnation}, {actual_revision})"),
            Self::RecordTombstoned { model } => write!(formatter, "projection record `{model}` is tombstoned; use explicit recreate"),
            Self::RecreateRequiresTombstone { model } => write!(formatter, "projection record `{model}` can only be recreated from its exact tombstone revision"),
            Self::CausalWriteRequired { table } => write!(formatter, "table `{table}` is causal-owned and requires the projection commit path"),
            Self::PositionOverflow { domain } => write!(formatter, "{domain} position overflow"),
        }
    }
}

impl std::error::Error for ProjectionProtocolError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            Self::Validation(error) => Some(error),
            Self::Repository(error) => Some(error),
            Self::Table(error) => Some(error),
            _ => None,
        }
    }
}

impl From<ProjectionProtocolValidationError> for ProjectionProtocolError {
    fn from(error: ProjectionProtocolValidationError) -> Self {
        Self::Validation(error)
    }
}

impl From<RepositoryError> for ProjectionProtocolError {
    fn from(error: RepositoryError) -> Self {
        Self::Repository(error)
    }
}

impl From<TableStoreError> for ProjectionProtocolError {
    fn from(error: TableStoreError) -> Self {
        Self::Table(error)
    }
}