use std::path::PathBuf;
use std::sync::Arc;
use std::{fmt, io};
use crate::Version;
#[derive(Debug, Clone, Error)]
pub enum LockError {
#[error("Could not acquire lock as it is already held, possibly by a different process.")]
LockBusy,
#[error("Failed to acquire the lock due to an io:Error.")]
IoError(Arc<io::Error>),
}
impl LockError {
pub fn wrap_io_error(io_error: io::Error) -> Self {
Self::IoError(Arc::new(io_error))
}
}
#[derive(Debug, Clone, Error)]
pub enum OpenDirectoryError {
#[error("Directory does not exist: '{0}'.")]
DoesNotExist(PathBuf),
#[error("Path exists but is not a directory: '{0}'.")]
NotADirectory(PathBuf),
#[error("Failed to create a temporary directory: '{0}'.")]
FailedToCreateTempDir(Arc<io::Error>),
#[error("IoError '{io_error:?}' while create directory in: '{directory_path:?}'.")]
IoError {
io_error: Arc<io::Error>,
directory_path: PathBuf,
},
}
impl OpenDirectoryError {
pub fn wrap_io_error(io_error: io::Error, directory_path: PathBuf) -> Self {
Self::IoError {
io_error: Arc::new(io_error),
directory_path,
}
}
}
#[derive(Debug, Clone, Error)]
pub enum OpenWriteError {
#[error("File already exists: '{0}'")]
FileAlreadyExists(PathBuf),
#[error("IoError '{io_error:?}' while opening file for write: '{filepath}'.")]
IoError {
io_error: Arc<io::Error>,
filepath: PathBuf,
},
}
impl OpenWriteError {
pub fn wrap_io_error(io_error: io::Error, filepath: PathBuf) -> Self {
Self::IoError {
io_error: Arc::new(io_error),
filepath,
}
}
}
#[derive(Clone)]
pub enum Incompatibility {
CompressionMismatch {
library_compression_format: String,
index_compression_format: String,
},
IndexMismatch {
library_version: Version,
index_version: Version,
},
}
impl fmt::Debug for Incompatibility {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self {
Incompatibility::CompressionMismatch {
library_compression_format,
index_compression_format,
} => {
let err = format!(
"Library was compiled with {library_compression_format:?} compression, index \
was compressed with {index_compression_format:?}"
);
let advice = format!(
"Change the feature flag to {index_compression_format:?} and rebuild the \
library"
);
write!(f, "{err}. {advice}")?;
}
Incompatibility::IndexMismatch {
library_version,
index_version,
} => {
let err = format!(
"Library version: {}, index version: {}",
library_version.index_format_version, index_version.index_format_version
);
let advice = format!(
"Change lucivy to a version compatible with index format {} (e.g. {}.{}.x) \
and rebuild your project.",
index_version.index_format_version, index_version.major, index_version.minor
);
write!(f, "{err}. {advice}")?;
}
}
Ok(())
}
}
#[derive(Debug, Clone, Error)]
pub enum OpenReadError {
#[error("Files does not exist: {0:?}")]
FileDoesNotExist(PathBuf),
#[error(
"IoError: '{io_error:?}' happened while opening the following file for Read: {filepath}."
)]
IoError {
io_error: Arc<io::Error>,
filepath: PathBuf,
},
#[error("Index version unsupported: {0:?}")]
IncompatibleIndex(Incompatibility),
}
impl OpenReadError {
pub fn wrap_io_error(io_error: io::Error, filepath: PathBuf) -> Self {
Self::IoError {
io_error: Arc::new(io_error),
filepath,
}
}
}
#[derive(Debug, Clone, Error)]
pub enum DeleteError {
#[error("File does not exist: '{0}'.")]
FileDoesNotExist(PathBuf),
#[error("The following IO error happened while deleting file '{filepath}': '{io_error:?}'.")]
IoError {
io_error: Arc<io::Error>,
filepath: PathBuf,
},
}
impl From<Incompatibility> for OpenReadError {
fn from(incompatibility: Incompatibility) -> Self {
OpenReadError::IncompatibleIndex(incompatibility)
}
}