1use std::error::Error as StdErr;
2use std::path::PathBuf;
3use std::{fmt, io};
4
5#[derive(Debug)]
7#[non_exhaustive]
8pub enum Error {
9 Parse(Box<toml::de::Error>),
11 Io(io::Error),
13 Workspace(Box<(Error, Option<PathBuf>)>),
15 InheritedUnknownValue,
17 WorkspaceIntegrity(String),
19 Other(&'static str),
21}
22
23impl StdErr for Error {
24 fn source(&self) -> Option<&(dyn StdErr + 'static)> {
25 match self {
26 Self::Parse(err) => Some(err),
27 Self::Io(err) => Some(err),
28 Self::Workspace(err) => Some(&err.0),
29 Self::Other(_) | Self::InheritedUnknownValue | Self::WorkspaceIntegrity(_) => None,
30 }
31 }
32}
33
34impl fmt::Display for Error {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 match self {
37 Self::Parse(err) => err.fmt(f),
38 Self::Io(err) => err.fmt(f),
39 Self::Other(msg) => f.write_str(msg),
40 Self::WorkspaceIntegrity(s) => f.write_str(s),
41 Self::Workspace(err_path) => {
42 f.write_str("can't load root workspace")?;
43 if let Some(path) = &err_path.1 {
44 write!(f, " at {}", path.display())?;
45 }
46 f.write_str(": ")?;
47 err_path.0.fmt(f)
48 },
49 Self::InheritedUnknownValue => f.write_str("value from workspace hasn't been set"),
50 }
51 }
52}
53
54impl Clone for Error {
55 fn clone(&self) -> Self {
56 match self {
57 Self::Parse(err) => Self::Parse(err.clone()),
58 Self::Io(err) => Self::Io(io::Error::new(err.kind(), err.to_string())),
59 Self::Other(msg) => Self::Other(msg),
60 Self::WorkspaceIntegrity(msg) => Self::WorkspaceIntegrity(msg.clone()),
61 Self::Workspace(e) => Self::Workspace(e.clone()),
62 Self::InheritedUnknownValue => Self::InheritedUnknownValue,
63 }
64 }
65}
66
67impl From<toml::de::Error> for Error {
68 fn from(o: toml::de::Error) -> Self {
69 Self::Parse(Box::new(o))
70 }
71}
72
73impl From<io::Error> for Error {
74 fn from(o: io::Error) -> Self {
75 Self::Io(o)
76 }
77}