kanban_persistence/
error.rs1use thiserror::Error;
2
3#[derive(Error, Debug)]
4pub enum PersistenceError {
5 #[error("IO error: {0}")]
6 Io(#[from] std::io::Error),
7
8 #[error("serialization error: {0}")]
9 Serialization(String),
10
11 #[error("database error: {0}")]
12 Database(String),
13
14 #[error("unsupported storage locator {locator:?}; supported: {}", supported.join(", "))]
15 UnsupportedLocator {
16 locator: String,
17 supported: Vec<String>,
18 },
19
20 #[error("file conflict: {path} was modified by another instance")]
21 ConflictDetected {
22 path: String,
23 #[source]
24 source: Option<Box<dyn std::error::Error + Send + Sync>>,
25 },
26
27 #[error("unsupported operation: {0}")]
28 Unsupported(String),
29}
30
31pub type PersistenceResult<T> = Result<T, PersistenceError>;
32
33impl From<PersistenceError> for kanban_domain::KanbanError {
34 fn from(e: PersistenceError) -> Self {
35 match e {
36 PersistenceError::Io(io) => kanban_domain::KanbanError::Io(io),
37 PersistenceError::Serialization(s) => kanban_domain::KanbanError::Serialization(s),
38 PersistenceError::Database(s) => kanban_domain::KanbanError::Database(s),
39 PersistenceError::UnsupportedLocator { locator, supported } => {
40 kanban_domain::KanbanError::Internal(format!(
41 "No backend registered for {:?}. Available backends: {}",
42 locator,
43 if supported.is_empty() {
44 "none".to_string()
45 } else {
46 supported.join(", ")
47 }
48 ))
49 }
50 PersistenceError::ConflictDetected { path, source } => {
51 kanban_domain::KanbanError::ConflictDetected { path, source }
52 }
53 PersistenceError::Unsupported(s) => kanban_domain::KanbanError::Internal(s),
54 }
55 }
56}