1use std::io;
2use std::path::PathBuf;
3
4use crate::pm::PmError;
5use crate::report::Report;
6
7#[derive(Debug)]
8pub enum AppError {
9 HomeDirUnavailable,
10 ReadConfig {
11 path: PathBuf,
12 source: io::Error,
13 },
14 ParseConfigToml(toml::de::Error),
15 CreateDir {
16 path: PathBuf,
17 source: io::Error,
18 },
19 InstallToolchain {
20 user: String,
21 repo: String,
22 source: String,
23 },
24 MissingToolchainSelection,
25 ToolchainNotInstalled {
26 toolchain: String,
27 path: PathBuf,
28 },
29 MoveToolchain {
30 from: PathBuf,
31 to: PathBuf,
32 source: io::Error,
33 },
34 RemoveToolchain {
35 path: PathBuf,
36 source: io::Error,
37 },
38 ReadScript {
39 path: PathBuf,
40 source: io::Error,
41 },
42 PackageManager(PmError),
43 ToolchainExecution {
44 toolchain: String,
45 message: String,
46 },
47}
48
49impl AppError {
50 pub fn report(&self) -> Report {
51 match self {
52 Self::HomeDirUnavailable => Report::new("could not resolve home directory")
53 .detail("`$HOME` is unavailable in the current environment"),
54 Self::ReadConfig { path, source } => Report::new("failed to read config")
55 .detail(format!("path: {}", path.display()))
56 .detail(format!("cause: {source}")),
57 Self::ParseConfigToml(source) => Report::new("failed to parse config")
58 .detail("expected a valid TOML document")
59 .detail(format!("cause: {source}")),
60 Self::CreateDir { path, source } => Report::new("failed to prepare directory")
61 .detail(format!("path: {}", path.display()))
62 .detail(format!("cause: {source}")),
63 Self::InstallToolchain { user, repo, source } => {
64 Report::new(format!("failed to install toolchain `{repo}`"))
65 .detail(format!("source: {user}/{repo}"))
66 .detail(format!("cause: {source}"))
67 }
68 Self::MissingToolchainSelection => Report::new("no toolchain is selected")
69 .detail("set `toolchain.name` in `~/.config/o-/config.toml`"),
70 Self::ToolchainNotInstalled { toolchain, path } => {
71 Report::new(format!("toolchain `{toolchain}` is not installed"))
72 .detail(format!("path: {}", path.display()))
73 .detail("install it with `o- toolchain add <user> <repo>`")
74 }
75 Self::MoveToolchain { from, to, source } => {
76 Report::new("failed to place installed toolchain")
77 .detail(format!("from: {}", from.display()))
78 .detail(format!("to: {}", to.display()))
79 .detail(format!("cause: {source}"))
80 }
81 Self::RemoveToolchain { path, source } => Report::new("failed to remove toolchain")
82 .detail(format!("path: {}", path.display()))
83 .detail(format!("cause: {source}")),
84 Self::ReadScript { path, source } => Report::new("failed to read script")
85 .detail(format!("path: {}", path.display()))
86 .detail(format!("cause: {source}")),
87 Self::PackageManager(error) => error.report(),
88 Self::ToolchainExecution { toolchain, message } => {
89 Report::new(format!("toolchain `{toolchain}` failed")).detail(message.clone())
90 }
91 }
92 }
93}