knowledge-base-crud 0.2.0

Filesystem CRUD operations for a file-based knowledge base
Documentation
use knowledge_base_validation::Diagnostic;
use std::fmt;
use std::io;
use std::path::PathBuf;

#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
    Read { path: PathBuf, source: io::Error },
    ParseStatementBatch { path: PathBuf, source: serde_yaml::Error },
    ParseReference { path: PathBuf, source: serde_yaml::Error },
    ParseAllocation { path: PathBuf, source: serde_yaml::Error },
    InvalidRequest(String),
    ParseEntity { path: PathBuf, source: serde_yaml::Error },
    InvalidRepository(String),
    Edit { path: PathBuf, message: String },
    Validation(Vec<Diagnostic>),
    Write { path: PathBuf, source: io::Error },
    ConcurrentChange(PathBuf),
    Commit { message: String },
}

impl fmt::Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Read { path, source } => write!(formatter, "cannot read {}: {source}", path.display()),
            Self::ParseStatementBatch { path, source } => {
                write!(formatter, "cannot parse statement manifest {}: {source}", path.display())
            }
            Self::ParseReference { path, source } => write!(formatter, "cannot parse reference {}: {source}", path.display()),
            Self::ParseAllocation { path, source } => write!(formatter, "cannot parse identifier allocation {}: {source}", path.display()),
            Self::InvalidRequest(message) => write!(formatter, "invalid mutation request: {message}"),
            Self::ParseEntity { path, source } => {
                write!(formatter, "cannot parse entity {}: {source}", path.display())
            }
            Self::InvalidRepository(message) => write!(formatter, "cannot query knowledge base: {message}"),
            Self::Edit { path, message } => {
                write!(formatter, "cannot edit resource {}: {message}", path.display())
            }
            Self::Validation(diagnostics) => {
                writeln!(formatter, "mutation would not produce a valid knowledge base:")?;
                for (index, diagnostic) in diagnostics.iter().enumerate() {
                    if index + 1 == diagnostics.len() {
                        write!(formatter, "{diagnostic}")?;
                    } else {
                        writeln!(formatter, "{diagnostic}")?;
                    }
                }
                Ok(())
            }
            Self::Write { path, source } => {
                write!(formatter, "cannot write {}: {source}", path.display())
            }
            Self::ConcurrentChange(path) => {
                write!(formatter, "resource changed while applying mutation: {}", path.display())
            }
            Self::Commit { message } => formatter.write_str(message),
        }
    }
}

impl std::error::Error for Error {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            Self::Read { source, .. } | Self::Write { source, .. } => Some(source),
            Self::ParseStatementBatch { source, .. } | Self::ParseReference { source, .. } | Self::ParseAllocation { source, .. } | Self::ParseEntity { source, .. } => {
                Some(source)
            }
            Self::InvalidRequest(_) | Self::InvalidRepository(_) | Self::Edit { .. } | Self::Validation(_) | Self::ConcurrentChange(_) | Self::Commit { .. } => None,
        }
    }
}