use std::{
env::set_current_dir,
path::{Path, PathBuf},
};
use miette::Diagnostic;
use thiserror::Error;
#[derive(Debug, Error, Diagnostic)]
#[error("failed to change the current directory to `{path}`")]
#[diagnostic(
code(changelogging::init::change_current_directory),
help("check whether the directory exists and is accessible")
)]
pub struct ChangeCurrentDirectoryError {
pub source: std::io::Error,
pub path: PathBuf,
}
impl ChangeCurrentDirectoryError {
pub fn new(source: std::io::Error, path: PathBuf) -> Self {
Self { source, path }
}
}
#[derive(Debug, Error, Diagnostic)]
#[error(transparent)]
#[diagnostic(transparent)]
pub enum ErrorSource {
ChangeCurrentDirectory(#[from] ChangeCurrentDirectoryError),
}
#[derive(Debug, Error, Diagnostic)]
#[error("failed to initialize")]
#[diagnostic(
code(changelogging::init::init),
help("see the report for more information")
)]
pub struct Error {
#[source]
#[diagnostic_source]
pub source: ErrorSource,
}
impl Error {
pub fn new(source: ErrorSource) -> Self {
Self { source }
}
pub fn change_current_directory(error: ChangeCurrentDirectoryError) -> Self {
Self::new(error.into())
}
pub fn new_change_current_directory(error: std::io::Error, path: PathBuf) -> Self {
Self::change_current_directory(ChangeCurrentDirectoryError::new(error, path))
}
}
pub fn init<D: AsRef<Path>>(directory: Option<D>) -> Result<(), Error> {
if let Some(path) = directory {
let path = path.as_ref();
set_current_dir(path)
.map_err(|error| Error::new_change_current_directory(error, path.to_owned()))?;
};
Ok(())
}