use std::{error::Error, fmt};
#[derive(PartialEq)]
pub struct CMDToolError {
pub details: String,
}
impl fmt::Display for CMDToolError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.details)
}
}
impl fmt::Debug for CMDToolError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
<Self as fmt::Display>::fmt(self, f)
}
}
impl Error for CMDToolError {
fn description(&self) -> &str {
&self.details
}
}
impl From<std::io::Error> for CMDToolError {
fn from(err: std::io::Error) -> Self {
CMDToolError {
details: err.to_string(),
}
}
}
impl From<rand_distr::NormalError> for CMDToolError {
fn from(err: rand_distr::NormalError) -> Self {
CMDToolError {
details: err.to_string(),
}
}
}
impl From<diskann::ANNError> for CMDToolError {
fn from(err: diskann::ANNError) -> Self {
CMDToolError {
details: err.to_string(),
}
}
}
impl From<diskann_utils::io::ReadBinError> for CMDToolError {
fn from(err: diskann_utils::io::ReadBinError) -> Self {
CMDToolError {
details: err.to_string(),
}
}
}
impl From<diskann_utils::io::SaveBinError> for CMDToolError {
fn from(err: diskann_utils::io::SaveBinError) -> Self {
CMDToolError {
details: err.to_string(),
}
}
}
impl From<diskann::graph::config::ConfigError> for CMDToolError {
fn from(err: diskann::graph::config::ConfigError) -> Self {
CMDToolError {
details: err.to_string(),
}
}
}
impl From<diskann_label_filter::JsonlReadError> for CMDToolError {
fn from(err: diskann_label_filter::JsonlReadError) -> Self {
CMDToolError {
details: err.to_string(),
}
}
}
impl<T, U> From<diskann_utils::io::MetadataError<T, U>> for CMDToolError
where
T: std::error::Error + Send + Sync + 'static,
U: std::error::Error + Send + Sync + 'static,
{
fn from(err: diskann_utils::io::MetadataError<T, U>) -> Self {
let ann_error: diskann::ANNError = err.into();
ann_error.into()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cmd_tool_error_display() {
let error = CMDToolError {
details: "test error".to_string(),
};
assert_eq!(format!("{}", error), "test error");
}
#[test]
fn test_cmd_tool_error_debug() {
let error = CMDToolError {
details: "test error".to_string(),
};
assert_eq!(format!("{:?}", error), "test error");
}
#[test]
fn test_cmd_tool_error_description() {
let error = CMDToolError {
details: "test error".to_string(),
};
#[allow(deprecated)]
{
assert_eq!(error.description(), "test error");
}
}
#[test]
fn test_from_io_error() {
let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
let cmd_error: CMDToolError = io_error.into();
assert!(cmd_error.details.contains("file not found"));
}
#[test]
fn test_from_normal_error() {
let normal_error = rand_distr::NormalError::BadVariance;
let cmd_error: CMDToolError = normal_error.into();
assert!(!cmd_error.details.is_empty());
}
#[test]
fn test_from_ann_error() {
use diskann::ANNErrorKind;
let ann_error = diskann::ANNError::new(
ANNErrorKind::IndexError,
std::io::Error::other("test error"),
);
let cmd_error: CMDToolError = ann_error.into();
assert!(cmd_error.details.contains("test error"));
}
#[test]
fn test_from_config_error() {
let config_error = diskann::graph::config::Builder::new(
10,
diskann::graph::config::MaxDegree::new(0),
50,
diskann::graph::config::PruneKind::TriangleInequality,
)
.build()
.unwrap_err();
let cmd_error: CMDToolError = config_error.into();
assert!(!cmd_error.details.is_empty());
}
#[test]
fn test_from_jsonl_read_error() {
use diskann_label_filter::JsonlReadError;
let jsonl_error = JsonlReadError::IoError(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"invalid jsonl",
));
let cmd_error: CMDToolError = jsonl_error.into();
assert!(cmd_error.details.contains("invalid jsonl"));
}
}