1use std::{fmt, path::PathBuf};
2
3pub type Result<T> = std::result::Result<T, RunbookError>;
4
5#[derive(Debug)]
6pub enum RunbookError {
7 CurrentDir(std::io::Error),
8 Io {
9 action: &'static str,
10 path: PathBuf,
11 source: std::io::Error,
12 },
13 PreferenceParse {
14 path: PathBuf,
15 source: serde_yaml::Error,
16 },
17 PreferenceWrite {
18 path: PathBuf,
19 source: serde_yaml::Error,
20 },
21 Usage {
22 reason: String,
23 help: &'static str,
24 },
25}
26
27impl RunbookError {
28 pub fn current_dir(error: std::io::Error) -> Self {
29 Self::CurrentDir(error)
30 }
31
32 pub fn usage(reason: String, help: &'static str) -> Self {
33 Self::Usage { reason, help }
34 }
35
36 pub fn io(action: &'static str, path: PathBuf, source: std::io::Error) -> Self {
37 Self::Io {
38 action,
39 path,
40 source,
41 }
42 }
43
44 pub fn preference_parse(path: PathBuf, source: serde_yaml::Error) -> Self {
45 Self::PreferenceParse { path, source }
46 }
47
48 pub fn preference_write(path: PathBuf, source: serde_yaml::Error) -> Self {
49 Self::PreferenceWrite { path, source }
50 }
51}
52
53impl fmt::Display for RunbookError {
54 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
55 match self {
56 Self::CurrentDir(error) => {
57 write!(formatter, "Failed to read current directory: {error}")
58 }
59 Self::Io {
60 action,
61 path,
62 source,
63 } => write!(formatter, "Failed to {action} {}: {source}", path.display()),
64 Self::PreferenceParse { path, source } => write!(
65 formatter,
66 "Failed to parse preference file {}: {source}",
67 path.display()
68 ),
69 Self::PreferenceWrite { path, source } => write!(
70 formatter,
71 "Failed to serialize preference file {}: {source}",
72 path.display()
73 ),
74 Self::Usage { reason, help } => write!(formatter, "{reason}\n\n{help}"),
75 }
76 }
77}
78
79impl std::error::Error for RunbookError {}