Skip to main content

o_/
app_error.rs

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