use std::fmt;
use std::path::PathBuf;
#[derive(Debug)]
pub(crate) enum ProjectError {
CurrentDirectory(std::io::Error),
InvalidConfig {
path: PathBuf,
source: toml::de::Error,
},
InvalidName(String),
InvalidField {
field: &'static str,
value: String,
},
NotFound(PathBuf),
ReadConfig {
path: PathBuf,
source: std::io::Error,
},
}
impl fmt::Display for ProjectError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::CurrentDirectory(error) => {
write!(formatter, "cannot inspect the current directory: {error}")
}
Self::InvalidConfig { path, source } => write!(
formatter,
"invalid Arcature project config {}: {source}",
path.display()
),
Self::InvalidName(name) => write!(
formatter,
"invalid project name `{name}`; use lowercase ASCII letters, digits, and single hyphens"
),
Self::InvalidField { field, value } => {
write!(
formatter,
"invalid `{field}` value `{value}` in arcature.toml"
)
}
Self::NotFound(start) => write!(
formatter,
"no Arcature project found from {}; expected arcature.toml in this directory or an ancestor",
start.display()
),
Self::ReadConfig { path, source } => write!(
formatter,
"cannot read Arcature project config {}: {source}",
path.display()
),
}
}
}
impl std::error::Error for ProjectError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::CurrentDirectory(error) => Some(error),
Self::InvalidConfig { source, .. } => Some(source),
Self::ReadConfig { source, .. } => Some(source),
Self::InvalidName(_) | Self::InvalidField { .. } | Self::NotFound(_) => None,
}
}
}