Skip to main content

starweaver_cli/
error.rs

1//! CLI error types.
2
3use std::{io, path::PathBuf};
4
5/// CLI result alias.
6pub type CliResult<T> = Result<T, CliError>;
7
8/// CLI failure.
9#[derive(Debug, thiserror::Error)]
10pub enum CliError {
11    /// Command-line parser failed.
12    #[error("{0}")]
13    Usage(String),
14    /// Configuration loading failed.
15    #[error("configuration error: {0}")]
16    Config(String),
17    /// Local storage failed.
18    #[error("storage error: {0}")]
19    Storage(String),
20    /// Requested record was missing.
21    #[error("not found: {0}")]
22    NotFound(String),
23    /// Filesystem operation failed.
24    #[error("filesystem error at {}: {source}", path.display())]
25    Io {
26        /// Path involved in the failure.
27        path: PathBuf,
28        /// Source IO error.
29        #[source]
30        source: io::Error,
31    },
32    /// Runtime execution failed.
33    #[error("run failed: {0}")]
34    Run(String),
35    /// Serialization failed.
36    #[error("serialization error: {0}")]
37    Serialization(String),
38}
39
40impl From<rusqlite::Error> for CliError {
41    fn from(error: rusqlite::Error) -> Self {
42        Self::Storage(error.to_string())
43    }
44}
45
46impl From<serde_json::Error> for CliError {
47    fn from(error: serde_json::Error) -> Self {
48        Self::Serialization(error.to_string())
49    }
50}
51
52impl From<toml::de::Error> for CliError {
53    fn from(error: toml::de::Error) -> Self {
54        Self::Config(error.to_string())
55    }
56}
57
58impl From<toml::ser::Error> for CliError {
59    fn from(error: toml::ser::Error) -> Self {
60        Self::Config(error.to_string())
61    }
62}
63
64/// Map an IO error with a path.
65pub fn io_error(path: impl Into<PathBuf>, source: io::Error) -> CliError {
66    CliError::Io {
67        path: path.into(),
68        source,
69    }
70}