1use std::path::PathBuf;
7
8use thiserror::Error;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13#[repr(u8)]
14pub enum ExitCode {
15 Ok = 0,
17 Failure = 1,
19 MissingDependency = 2,
21 UserCancelled = 3,
23 ConfirmationMismatch = 4,
25 InvalidArgument = 5,
27}
28
29impl From<ExitCode> for u8 {
30 fn from(e: ExitCode) -> Self {
31 e as u8
32 }
33}
34
35#[derive(Debug, Error)]
39pub enum Error {
40 #[error("command `{cmd}` exited with status {status}: {stderr}")]
43 CommandFailed {
44 cmd: String,
45 status: i32,
46 stderr: String,
47 #[source]
48 io: Option<std::io::Error>,
49 },
50
51 #[error("missing dependency `{binary}`: {detail}")]
54 MissingDependency {
55 binary: String,
56 detail: String,
57 hint: Option<String>,
58 #[source]
59 io: Option<std::io::Error>,
60 },
61
62 #[error("config error: {0}")]
64 Config(#[from] ConfigError),
65
66 #[error("no matching NTFS volume for `{pattern}`")]
69 NoMatch { pattern: String },
70
71 #[error("confirmation mismatch: expected `{expected}`, got `{actual}`")]
73 ConfirmationMismatch { expected: String, actual: String },
74
75 #[error("user cancelled")]
77 Cancelled,
78
79 #[error("invalid argument: {0}")]
81 InvalidArgument(String),
82
83 #[error("i/o error: {0}")]
87 Io(#[from] std::io::Error),
88
89 #[error("serialization error: {0}")]
91 Serde(String),
92}
93
94#[derive(Debug, Error)]
95pub enum ConfigError {
96 #[error("failed to read config at {path}: {reason}")]
97 Read { path: PathBuf, reason: String },
98 #[error("failed to write config to {path}: {reason}")]
99 Write { path: PathBuf, reason: String },
100 #[error("config parse error at {path}: {reason}")]
101 Parse { path: PathBuf, reason: String },
102}
103
104impl From<ConfigError> for std::io::Error {
105 fn from(e: ConfigError) -> Self {
106 std::io::Error::other(e.to_string())
107 }
108}
109
110pub type Result<T> = std::result::Result<T, Error>;