weavatrix-memory 0.3.0

Event-sourced, bitemporal context compiler for coding agents
Documentation
use core::fmt;

pub type Result<T> = core::result::Result<T, MemoryError>;

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum MemoryError {
    InvalidId {
        kind: &'static str,
        value: String,
    },
    InvalidValue {
        field: &'static str,
        reason: &'static str,
    },
    VersionConflict {
        stream: String,
        expected: Option<u64>,
        actual: Option<u64>,
    },
    DuplicateEvent {
        id: String,
    },
    InvalidReplay {
        reason: String,
    },
    MissingEntity {
        id: String,
    },
    MissingFact {
        id: String,
    },
    ConflictingFact {
        id: String,
    },
    BudgetTooSmall {
        required: usize,
        available: usize,
    },
    CapacityOverflow,
    Io {
        operation: &'static str,
        message: String,
    },
    Codec {
        message: String,
    },
    CorruptLog {
        offset: u64,
        reason: String,
    },
    ExternalModification,
    Retrieval {
        provider: String,
        message: String,
    },
    Extraction {
        provider: String,
        message: String,
    },
    Graph(String),
}

impl fmt::Display for MemoryError {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::InvalidId { kind, value } => {
                write!(formatter, "invalid {kind} identifier: {value:?}")
            }
            Self::InvalidValue { field, reason } => {
                write!(formatter, "invalid {field}: {reason}")
            }
            Self::VersionConflict {
                stream,
                expected,
                actual,
            } => write!(
                formatter,
                "version conflict for {stream}: expected {expected:?}, actual {actual:?}"
            ),
            Self::DuplicateEvent { id } => write!(formatter, "duplicate event identifier: {id}"),
            Self::InvalidReplay { reason } => write!(formatter, "invalid replay: {reason}"),
            Self::MissingEntity { id } => write!(formatter, "missing memory entity: {id}"),
            Self::MissingFact { id } => write!(formatter, "missing memory fact: {id}"),
            Self::ConflictingFact { id } => write!(formatter, "conflicting memory fact: {id}"),
            Self::BudgetTooSmall {
                required,
                available,
            } => write!(
                formatter,
                "context budget needs {required} tokens but only {available} are available"
            ),
            Self::CapacityOverflow => formatter.write_str("event store capacity exceeded"),
            Self::Io { operation, message } => {
                write!(formatter, "I/O error during {operation}: {message}")
            }
            Self::Codec { message } => write!(formatter, "codec failed: {message}"),
            Self::CorruptLog { offset, reason } => {
                write!(formatter, "corrupt event log at byte {offset}: {reason}")
            }
            Self::ExternalModification => {
                formatter.write_str("event log was modified by another writer")
            }
            Self::Retrieval { provider, message } => {
                write!(formatter, "retrieval provider {provider} failed: {message}")
            }
            Self::Extraction { provider, message } => {
                write!(
                    formatter,
                    "extraction provider {provider} failed: {message}"
                )
            }
            Self::Graph(reason) => write!(formatter, "graph projection failed: {reason}"),
        }
    }
}

impl std::error::Error for MemoryError {}

impl From<weavatrix_graph::GraphError> for MemoryError {
    fn from(value: weavatrix_graph::GraphError) -> Self {
        Self::Graph(value.to_string())
    }
}

impl From<crate::RetrievalError> for MemoryError {
    fn from(value: crate::RetrievalError) -> Self {
        Self::Retrieval {
            provider: value.provider,
            message: value.message,
        }
    }
}

impl From<crate::ExtractionError> for MemoryError {
    fn from(value: crate::ExtractionError) -> Self {
        Self::Extraction {
            provider: value.provider,
            message: value.message,
        }
    }
}