Skip to main content

knowledge_base_crud/
error.rs

1use knowledge_base_snapshot::Error as SnapshotError;
2use knowledge_base_validation::Diagnostic;
3use std::fmt;
4use std::io;
5use std::path::PathBuf;
6
7#[derive(Debug)]
8#[non_exhaustive]
9pub enum RepositoryError {
10    Read { path: PathBuf, source: io::Error },
11    ParseStatementBatch { path: PathBuf, source: serde_yaml::Error },
12    ParseReference { path: PathBuf, source: serde_yaml::Error },
13    ParseAllocation { path: PathBuf, source: serde_yaml::Error },
14    ParseEntityType { path: PathBuf, source: serde_yaml::Error },
15    ParseProperty { path: PathBuf, source: serde_yaml::Error },
16    InvalidRequest(String),
17    ParseEntity { path: PathBuf, source: serde_yaml::Error },
18    Snapshot(SnapshotError),
19    InvalidRepository(String),
20    InvalidSnapshot { path: PathBuf, message: String },
21    Edit { path: PathBuf, message: String },
22    Validation(Vec<Diagnostic>),
23    Write { path: PathBuf, source: io::Error },
24    ConcurrentChange(PathBuf),
25    Commit { message: String },
26}
27
28impl fmt::Display for RepositoryError {
29    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
30        match self {
31            Self::Read { path, source } => write!(formatter, "cannot read {}: {source}", path.display()),
32            Self::ParseStatementBatch { path, source } => {
33                write!(formatter, "cannot parse statement manifest {}: {source}", path.display())
34            }
35            Self::ParseReference { path, source } => write!(formatter, "cannot parse reference {}: {source}", path.display()),
36            Self::ParseAllocation { path, source } => write!(formatter, "cannot parse identifier allocation {}: {source}", path.display()),
37            Self::ParseEntityType { path, source } => write!(formatter, "cannot parse entity type {}: {source}", path.display()),
38            Self::ParseProperty { path, source } => write!(formatter, "cannot parse property {}: {source}", path.display()),
39            Self::InvalidRequest(message) => write!(formatter, "invalid mutation request: {message}"),
40            Self::ParseEntity { path, source } => {
41                write!(formatter, "cannot parse entity {}: {source}", path.display())
42            }
43            Self::InvalidRepository(message) => write!(formatter, "cannot query knowledge base: {message}"),
44            Self::Snapshot(source) => source.fmt(formatter),
45            Self::InvalidSnapshot { path, message } => write!(formatter, "cannot load repository snapshot at {}: {message}", path.display()),
46            Self::Edit { path, message } => {
47                write!(formatter, "cannot edit resource {}: {message}", path.display())
48            }
49            Self::Validation(diagnostics) => {
50                writeln!(formatter, "mutation would not produce a valid knowledge base:")?;
51                for (index, diagnostic) in diagnostics.iter().enumerate() {
52                    if index + 1 == diagnostics.len() {
53                        write!(formatter, "{diagnostic}")?;
54                    } else {
55                        writeln!(formatter, "{diagnostic}")?;
56                    }
57                }
58                Ok(())
59            }
60            Self::Write { path, source } => {
61                write!(formatter, "cannot write {}: {source}", path.display())
62            }
63            Self::ConcurrentChange(path) => {
64                write!(formatter, "resource changed while applying mutation: {}", path.display())
65            }
66            Self::Commit { message } => formatter.write_str(message),
67        }
68    }
69}
70
71impl std::error::Error for RepositoryError {
72    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
73        match self {
74            Self::Read { source, .. } | Self::Write { source, .. } => Some(source),
75            Self::ParseStatementBatch { source, .. }
76            | Self::ParseReference { source, .. }
77            | Self::ParseAllocation { source, .. }
78            | Self::ParseEntityType { source, .. }
79            | Self::ParseProperty { source, .. }
80            | Self::ParseEntity { source, .. } => Some(source),
81            Self::Snapshot(source) => Some(source),
82            Self::InvalidRequest(_)
83            | Self::InvalidRepository(_)
84            | Self::InvalidSnapshot { .. }
85            | Self::Edit { .. }
86            | Self::Validation(_)
87            | Self::ConcurrentChange(_)
88            | Self::Commit { .. } => None,
89        }
90    }
91}