ricecoder_storage/
error.rs

1//! Storage error types for RiceCoder
2
3use std::path::PathBuf;
4use thiserror::Error;
5
6/// Result type for storage operations
7pub type StorageResult<T> = Result<T, StorageError>;
8
9/// Storage error types
10#[derive(Error, Debug)]
11pub enum StorageError {
12    /// Directory creation failed
13    #[error("Directory creation failed for {path}: {source}")]
14    DirectoryCreationFailed {
15        path: PathBuf,
16        source: std::io::Error,
17    },
18
19    /// File read/write failed
20    #[error("IO error on {path} ({operation}): {source}")]
21    IoError {
22        path: PathBuf,
23        operation: IoOperation,
24        source: std::io::Error,
25    },
26
27    /// Configuration parsing failed
28    #[error("Failed to parse {path} as {format}: {message}")]
29    ParseError {
30        path: PathBuf,
31        format: String,
32        message: String,
33    },
34
35    /// Invalid configuration value
36    #[error("Invalid configuration value for {field}: {message}")]
37    ValidationError { field: String, message: String },
38
39    /// Path resolution failed
40    #[error("Path resolution failed: {message}")]
41    PathResolutionError { message: String },
42
43    /// Environment variable error
44    #[error("Environment variable error for {var_name}: {message}")]
45    EnvVarError { var_name: String, message: String },
46
47    /// Relocation failed
48    #[error("Failed to relocate storage from {from} to {to}: {message}")]
49    RelocationError {
50        from: PathBuf,
51        to: PathBuf,
52        message: String,
53    },
54
55    /// Offline mode - storage unavailable
56    #[error("Storage unavailable at {path}: {message}")]
57    StorageUnavailable { path: PathBuf, message: String },
58
59    /// First-run confirmation required
60    #[error("First-run confirmation required. Suggested path: {suggested_path}")]
61    FirstRunConfirmationRequired { suggested_path: PathBuf },
62
63    /// Generic IO error
64    #[error("IO error: {0}")]
65    Io(#[from] std::io::Error),
66
67    /// Internal error
68    #[error("Internal error: {0}")]
69    Internal(String),
70}
71
72/// IO operation type for error context
73#[derive(Debug, Clone, Copy)]
74pub enum IoOperation {
75    Read,
76    Write,
77    Delete,
78    Move,
79}
80
81impl std::fmt::Display for IoOperation {
82    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83        match self {
84            IoOperation::Read => write!(f, "read"),
85            IoOperation::Write => write!(f, "write"),
86            IoOperation::Delete => write!(f, "delete"),
87            IoOperation::Move => write!(f, "move"),
88        }
89    }
90}
91
92impl StorageError {
93    /// Create a directory creation failed error
94    pub fn directory_creation_failed(path: PathBuf, source: std::io::Error) -> Self {
95        StorageError::DirectoryCreationFailed { path, source }
96    }
97
98    /// Create an IO error
99    pub fn io_error(path: PathBuf, operation: IoOperation, source: std::io::Error) -> Self {
100        StorageError::IoError {
101            path,
102            operation,
103            source,
104        }
105    }
106
107    /// Create a parse error
108    pub fn parse_error(
109        path: PathBuf,
110        format: impl Into<String>,
111        message: impl Into<String>,
112    ) -> Self {
113        StorageError::ParseError {
114            path,
115            format: format.into(),
116            message: message.into(),
117        }
118    }
119
120    /// Create a validation error
121    pub fn validation_error(field: impl Into<String>, message: impl Into<String>) -> Self {
122        StorageError::ValidationError {
123            field: field.into(),
124            message: message.into(),
125        }
126    }
127
128    /// Create a path resolution error
129    pub fn path_resolution_error(message: impl Into<String>) -> Self {
130        StorageError::PathResolutionError {
131            message: message.into(),
132        }
133    }
134
135    /// Create an environment variable error
136    pub fn env_var_error(var_name: impl Into<String>, message: impl Into<String>) -> Self {
137        StorageError::EnvVarError {
138            var_name: var_name.into(),
139            message: message.into(),
140        }
141    }
142
143    /// Create a relocation error
144    pub fn relocation_error(from: PathBuf, to: PathBuf, message: impl Into<String>) -> Self {
145        StorageError::RelocationError {
146            from,
147            to,
148            message: message.into(),
149        }
150    }
151
152    /// Create a storage unavailable error
153    pub fn storage_unavailable(path: PathBuf, message: impl Into<String>) -> Self {
154        StorageError::StorageUnavailable {
155            path,
156            message: message.into(),
157        }
158    }
159
160    /// Create a first-run confirmation required error
161    pub fn first_run_confirmation_required(suggested_path: PathBuf) -> Self {
162        StorageError::FirstRunConfirmationRequired { suggested_path }
163    }
164
165    /// Create an internal error
166    pub fn internal(message: impl Into<String>) -> Self {
167        StorageError::Internal(message.into())
168    }
169}