use std::io;
use crate::config::args::ArgsError;
use crate::config::file::ConfigFileError;
#[cfg(feature = "_tiles")]
use crate::config::file::SourceBuildError;
use crate::srv::ServerStartError;
pub type StartupResult<T> = Result<T, StartupError>;
#[derive(thiserror::Error, Debug)]
pub enum StartupError {
#[error(transparent)]
Args(#[from] ArgsError),
#[error(transparent)]
Config(#[from] ConfigFileError),
#[cfg(feature = "_tiles")]
#[error(transparent)]
SourceBuild(#[from] SourceBuildError),
#[error(transparent)]
Server(#[from] ServerStartError),
#[error(transparent)]
Io(#[from] io::Error),
}
impl StartupError {
#[must_use]
pub fn render_diagnostic(&self) -> String {
self.render_diagnostic_with(crate::logging::LogFormat::default())
}
#[must_use]
pub fn render_diagnostic_with(&self, format: crate::logging::LogFormat) -> String {
if let Some(report) = self
.spanned_config_error()
.and_then(ConfigFileError::to_miette_report)
{
if format.is_json() {
let mut buf = String::new();
miette::JSONReportHandler::new()
.render_report(&mut buf, report.as_ref())
.expect("rendering into a String is infallible");
return buf;
}
return format!("{report:?}");
}
if format.is_json() {
let message = serde_json::to_string(&self.to_string())
.expect("string serialization is infallible");
return format!(r#"{{"message": {message}}}"#);
}
format!("{self}")
}
const fn spanned_config_error(&self) -> Option<&ConfigFileError> {
match self {
Self::Config(e) => Some(e),
#[cfg(feature = "_tiles")]
Self::SourceBuild(SourceBuildError::Config(e)) => Some(e),
_ => None,
}
}
}