cargo_image_runner/core/
error.rs1use std::path::PathBuf;
2
3pub type Result<T> = std::result::Result<T, Error>;
5
6#[derive(Debug, thiserror::Error)]
8pub enum Error {
9 #[error("Configuration error: {0}")]
11 Config(String),
12
13 #[error("Bootloader error: {0}")]
15 Bootloader(String),
16
17 #[error("Image build error: {0}")]
19 ImageBuild(String),
20
21 #[error("Runner error: {0}")]
23 Runner(String),
24
25 #[error("Firmware error: {0}")]
27 Firmware(String),
28
29 #[error("Template error: {0}")]
31 Template(String),
32
33 #[error("File not found: {}", .0.display())]
35 FileNotFound(PathBuf),
36
37 #[error("Missing required configuration field: {0}")]
39 MissingConfig(String),
40
41 #[error("Invalid configuration value for {field}: {value}")]
43 InvalidConfig { field: String, value: String },
44
45 #[error("Feature '{0}' is not enabled. Enable it in Cargo.toml features.")]
47 FeatureNotEnabled(String),
48
49 #[error("Unsupported combination: {0}")]
51 UnsupportedCombination(String),
52
53 #[error("IO error: {0}")]
55 Io(#[from] std::io::Error),
56
57 #[error("TOML parsing error: {0}")]
59 TomlDe(#[from] toml::de::Error),
60
61 #[error("JSON error: {0}")]
63 Json(#[from] serde_json::Error),
64
65 #[cfg(feature = "cargo-metadata")]
67 #[error("Cargo metadata error: {0}")]
68 CargoMetadata(#[from] cargo_metadata::Error),
69
70 #[cfg(feature = "limine")]
72 #[error("Git error: {0}")]
73 Git(#[from] git2::Error),
74}
75
76impl Error {
77 pub fn config(msg: impl Into<String>) -> Self {
79 Error::Config(msg.into())
80 }
81
82 pub fn bootloader(msg: impl Into<String>) -> Self {
84 Error::Bootloader(msg.into())
85 }
86
87 pub fn image_build(msg: impl Into<String>) -> Self {
89 Error::ImageBuild(msg.into())
90 }
91
92 pub fn runner(msg: impl Into<String>) -> Self {
94 Error::Runner(msg.into())
95 }
96
97 pub fn firmware(msg: impl Into<String>) -> Self {
99 Error::Firmware(msg.into())
100 }
101
102 pub fn template(msg: impl Into<String>) -> Self {
104 Error::Template(msg.into())
105 }
106
107 pub fn feature_not_enabled(feature: impl Into<String>) -> Self {
109 Error::FeatureNotEnabled(feature.into())
110 }
111
112 pub fn unsupported(msg: impl Into<String>) -> Self {
114 Error::UnsupportedCombination(msg.into())
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121
122 #[test]
123 fn test_error_display_messages() {
124 assert_eq!(
125 Error::config("bad value").to_string(),
126 "Configuration error: bad value"
127 );
128 assert_eq!(
129 Error::bootloader("fetch failed").to_string(),
130 "Bootloader error: fetch failed"
131 );
132 assert_eq!(
133 Error::image_build("write error").to_string(),
134 "Image build error: write error"
135 );
136 assert_eq!(
137 Error::runner("not found").to_string(),
138 "Runner error: not found"
139 );
140 assert_eq!(
141 Error::firmware("missing file").to_string(),
142 "Firmware error: missing file"
143 );
144 assert_eq!(
145 Error::template("bad syntax").to_string(),
146 "Template error: bad syntax"
147 );
148 assert_eq!(
149 Error::feature_not_enabled("grub").to_string(),
150 "Feature 'grub' is not enabled. Enable it in Cargo.toml features."
151 );
152 assert_eq!(
153 Error::unsupported("bios + fat").to_string(),
154 "Unsupported combination: bios + fat"
155 );
156 }
157
158 #[test]
159 fn test_error_file_not_found() {
160 let err = Error::FileNotFound(PathBuf::from("/missing/file.txt"));
161 assert_eq!(err.to_string(), "File not found: /missing/file.txt");
162 }
163
164 #[test]
165 fn test_error_missing_config() {
166 let err = Error::MissingConfig("boot.type".to_string());
167 assert_eq!(
168 err.to_string(),
169 "Missing required configuration field: boot.type"
170 );
171 }
172
173 #[test]
174 fn test_error_invalid_config() {
175 let err = Error::InvalidConfig {
176 field: "boot.type".to_string(),
177 value: "unknown".to_string(),
178 };
179 assert_eq!(
180 err.to_string(),
181 "Invalid configuration value for boot.type: unknown"
182 );
183 }
184}