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    MissingConfigField(&'static str),
16    CreateDir {
17        path: PathBuf,
18        source: io::Error,
19    },
20    InstallToolchain {
21        user: String,
22        repo: String,
23        source: String,
24    },
25    MoveToolchain {
26        from: PathBuf,
27        to: PathBuf,
28        source: io::Error,
29    },
30    RemoveToolchain {
31        path: PathBuf,
32        source: io::Error,
33    },
34    ReadScript {
35        path: PathBuf,
36        source: io::Error,
37    },
38    PackageManager(PmError),
39    UnsupportedToolchain {
40        toolchain: String,
41        detail: &'static str,
42    },
43}
44
45impl AppError {
46    pub fn report(&self) -> Report {
47        match self {
48            Self::HomeDirUnavailable => Report::new("could not resolve home directory")
49                .detail("`$HOME` is unavailable in the current environment"),
50            Self::ReadConfig { path, source } => Report::new("failed to read config")
51                .detail(format!("path: {}", path.display()))
52                .detail(format!("cause: {source}")),
53            Self::ParseConfigToml(source) => Report::new("failed to parse config")
54                .detail("expected a valid TOML document")
55                .detail(format!("cause: {source}")),
56            Self::MissingConfigField(field) => {
57                Report::new("config is missing a required field").detail(format!("field: {field}"))
58            }
59            Self::CreateDir { path, source } => Report::new("failed to prepare directory")
60                .detail(format!("path: {}", path.display()))
61                .detail(format!("cause: {source}")),
62            Self::InstallToolchain { user, repo, source } => {
63                Report::new(format!("failed to install toolchain `{repo}`"))
64                    .detail(format!("source: {user}/{repo}"))
65                    .detail(format!("cause: {source}"))
66            }
67            Self::MoveToolchain { from, to, source } => {
68                Report::new("failed to place installed toolchain")
69                    .detail(format!("from: {}", from.display()))
70                    .detail(format!("to: {}", to.display()))
71                    .detail(format!("cause: {source}"))
72            }
73            Self::RemoveToolchain { path, source } => Report::new("failed to remove toolchain")
74                .detail(format!("path: {}", path.display()))
75                .detail(format!("cause: {source}")),
76            Self::ReadScript { path, source } => Report::new("failed to read script")
77                .detail(format!("path: {}", path.display()))
78                .detail(format!("cause: {source}")),
79            Self::PackageManager(error) => error.report(),
80            Self::UnsupportedToolchain { toolchain, detail } => Report::new(format!(
81                "toolchain `{toolchain}` is not supported on this platform"
82            ))
83            .detail(*detail),
84        }
85    }
86}