codeprysm_config/
error.rs

1//! Configuration error types.
2
3use std::path::PathBuf;
4use thiserror::Error;
5
6/// Errors that can occur during configuration loading.
7#[derive(Error, Debug)]
8pub enum ConfigError {
9    /// Failed to read configuration file
10    #[error("failed to read config file '{path}': {source}")]
11    ReadFile {
12        path: PathBuf,
13        #[source]
14        source: std::io::Error,
15    },
16
17    /// Failed to parse TOML configuration
18    #[error("failed to parse config file '{path}': {source}")]
19    ParseToml {
20        path: PathBuf,
21        #[source]
22        source: toml::de::Error,
23    },
24
25    /// Failed to serialize configuration
26    #[error("failed to serialize config: {0}")]
27    Serialize(#[from] toml::ser::Error),
28
29    /// Failed to write configuration file
30    #[error("failed to write config file '{path}': {source}")]
31    WriteFile {
32        path: PathBuf,
33        #[source]
34        source: std::io::Error,
35    },
36
37    /// Failed to create configuration directory
38    #[error("failed to create config directory '{path}': {source}")]
39    CreateDir {
40        path: PathBuf,
41        #[source]
42        source: std::io::Error,
43    },
44
45    /// Home directory not found
46    #[error("could not determine home directory")]
47    NoHomeDir,
48
49    /// Invalid configuration value
50    #[error("invalid configuration value for '{key}': {message}")]
51    InvalidValue { key: String, message: String },
52
53    /// Workspace not found
54    #[error("workspace '{name}' not found in configuration")]
55    WorkspaceNotFound { name: String },
56
57    /// Configuration validation error
58    #[error("configuration validation failed: {0}")]
59    ValidationError(String),
60}
61
62impl ConfigError {
63    /// Create a new ReadFile error.
64    pub fn read_file(path: impl Into<PathBuf>, source: std::io::Error) -> Self {
65        Self::ReadFile {
66            path: path.into(),
67            source,
68        }
69    }
70
71    /// Create a new ParseToml error.
72    pub fn parse_toml(path: impl Into<PathBuf>, source: toml::de::Error) -> Self {
73        Self::ParseToml {
74            path: path.into(),
75            source,
76        }
77    }
78
79    /// Create a new WriteFile error.
80    pub fn write_file(path: impl Into<PathBuf>, source: std::io::Error) -> Self {
81        Self::WriteFile {
82            path: path.into(),
83            source,
84        }
85    }
86
87    /// Create a new CreateDir error.
88    pub fn create_dir(path: impl Into<PathBuf>, source: std::io::Error) -> Self {
89        Self::CreateDir {
90            path: path.into(),
91            source,
92        }
93    }
94
95    /// Create a new InvalidValue error.
96    pub fn invalid_value(key: impl Into<String>, message: impl Into<String>) -> Self {
97        Self::InvalidValue {
98            key: key.into(),
99            message: message.into(),
100        }
101    }
102
103    /// Create a new WorkspaceNotFound error.
104    pub fn workspace_not_found(name: impl Into<String>) -> Self {
105        Self::WorkspaceNotFound { name: name.into() }
106    }
107}
108
109#[cfg(test)]
110mod tests {
111    use super::*;
112
113    #[test]
114    fn test_error_display() {
115        let err = ConfigError::NoHomeDir;
116        assert_eq!(err.to_string(), "could not determine home directory");
117
118        let err = ConfigError::invalid_value("backend.type", "unknown backend 'foo'");
119        assert!(err.to_string().contains("backend.type"));
120        assert!(err.to_string().contains("unknown backend"));
121    }
122
123    #[test]
124    fn test_workspace_not_found() {
125        let err = ConfigError::workspace_not_found("my-project");
126        assert!(err.to_string().contains("my-project"));
127        assert!(err.to_string().contains("not found"));
128    }
129}