Skip to main content

conduit_cli/core/
error.rs

1use std::fmt;
2
3#[derive(Debug)]
4pub enum CoreError {
5    Io(std::io::Error),
6    Json(serde_json::Error),
7    TomlDe(toml::de::Error),
8    TomlSer(toml::ser::Error),
9    Reqwest(reqwest::Error),
10    MissingConfig,
11    MissingLocalDataDir,
12    NoCompatibleVersion { slug: String },
13    NoFilesForVersion { version: String },
14    ProjectNotFound { slug: String },
15    UnsupportedLoader(String),
16    ServerOnlyFeature,
17    ClientOnlyFeature,
18    RuntimeError(String),
19    Zip(zip::result::ZipError),
20    MissingLocalFiles { mods: Vec<(String, String)> },
21}
22
23impl fmt::Display for CoreError {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        match self {
26            CoreError::Io(e) => write!(f, "IO error: {e}"),
27            CoreError::Json(e) => write!(f, "JSON error: {e}"),
28            CoreError::TomlDe(e) => write!(f, "TOML decode error: {e}"),
29            CoreError::TomlSer(e) => write!(f, "TOML encode error: {e}"),
30            CoreError::Reqwest(e) => write!(f, "HTTP error: {e}"),
31            CoreError::MissingConfig => write!(f, "No conduit.json found"),
32            CoreError::MissingLocalDataDir => write!(f, "Could not find local data directory"),
33            CoreError::NoCompatibleVersion { slug } => {
34                write!(f, "No compatible version for {slug}")
35            }
36            CoreError::NoFilesForVersion { version } => {
37                write!(f, "No files available for version {version}")
38            }
39            CoreError::ProjectNotFound { slug } => write!(f, "Project not found: {slug}"),
40            CoreError::UnsupportedLoader(loader) => {
41                write!(f, "Unsupported loader: {loader}")
42            }
43            CoreError::ServerOnlyFeature => {
44                write!(f, "This feature is only available for server instances")
45            }
46            CoreError::ClientOnlyFeature => {
47                write!(f, "This feature is only available for client instances")
48            }
49            CoreError::RuntimeError(e) => write!(f, "Runtime error: {e}"),
50            CoreError::Zip(e) => write!(f, "Zip error: {e}"),
51            CoreError::MissingLocalFiles { mods } => {
52                let list = mods
53                    .iter()
54                    .map(|(slug, file)| format!("{slug} ({file})"))
55                    .collect::<Vec<_>>()
56                    .join(", ");
57                write!(f, "Missing local mod files: {list}")
58            }
59        }
60    }
61}
62
63impl std::error::Error for CoreError {}
64
65impl From<std::io::Error> for CoreError {
66    fn from(value: std::io::Error) -> Self {
67        Self::Io(value)
68    }
69}
70
71impl From<serde_json::Error> for CoreError {
72    fn from(value: serde_json::Error) -> Self {
73        Self::Json(value)
74    }
75}
76
77impl From<toml::de::Error> for CoreError {
78    fn from(value: toml::de::Error) -> Self {
79        Self::TomlDe(value)
80    }
81}
82
83impl From<toml::ser::Error> for CoreError {
84    fn from(value: toml::ser::Error) -> Self {
85        Self::TomlSer(value)
86    }
87}
88
89impl From<reqwest::Error> for CoreError {
90    fn from(value: reqwest::Error) -> Self {
91        Self::Reqwest(value)
92    }
93}
94
95pub type CoreResult<T> = Result<T, CoreError>;
96
97impl From<Box<dyn std::error::Error>> for CoreError {
98    fn from(value: Box<dyn std::error::Error>) -> Self {
99        Self::RuntimeError(value.to_string())
100    }
101}
102
103impl From<zip::result::ZipError> for CoreError {
104    fn from(value: zip::result::ZipError) -> Self {
105        Self::Zip(value)
106    }
107}