Skip to main content

o_/
app_error.rs

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}