Skip to main content

faiss_next/
error.rs

1use std::ffi::{CStr, NulError};
2use std::io;
3
4use faiss_next_sys;
5
6#[derive(Debug, thiserror::Error)]
7pub enum Error {
8    #[error("Faiss native error (code={code}): {message}")]
9    Native { code: i32, message: String },
10
11    #[error("Invalid index description: {0}")]
12    InvalidDescription(String),
13
14    #[error("Index not trained")]
15    NotTrained,
16
17    #[error("Index is empty")]
18    EmptyIndex,
19
20    #[error("Invalid dimension: expected {expected}, got {actual}")]
21    InvalidDimension { expected: usize, actual: usize },
22
23    #[error("Invalid parameter: {0}")]
24    InvalidParameter(String),
25
26    #[error("Invalid cast to {target}: {reason}")]
27    InvalidCast {
28        target: &'static str,
29        reason: String,
30    },
31
32    #[error("Null pointer encountered")]
33    NullPointer,
34
35    #[error("Index does not support operation: {0}")]
36    UnsupportedOperation(&'static str),
37
38    #[error("IO error: {0}")]
39    Io(#[from] io::Error),
40
41    #[error("UTF-8 error: {0}")]
42    Utf8(#[from] NulError),
43}
44
45pub type Result<T> = std::result::Result<T, Error>;
46
47#[inline]
48pub(crate) fn check_return_code(code: i32) -> Result<()> {
49    if code == faiss_next_sys::FAISS_OK {
50        return Ok(());
51    }
52
53    let message = unsafe {
54        let ptr = faiss_next_sys::faiss_get_last_error();
55        if ptr.is_null() {
56            "unknown error".to_string()
57        } else {
58            CStr::from_ptr(ptr)
59                .to_str()
60                .unwrap_or("invalid error message")
61                .to_string()
62        }
63    };
64
65    Err(Error::Native { code, message })
66}
67
68impl Error {
69    pub fn native(code: i32, message: impl Into<String>) -> Self {
70        Error::Native {
71            code,
72            message: message.into(),
73        }
74    }
75
76    pub fn invalid_cast(target: &'static str, reason: impl Into<String>) -> Self {
77        Error::InvalidCast {
78            target,
79            reason: reason.into(),
80        }
81    }
82
83    pub fn unsupported(operation: &'static str) -> Self {
84        Error::UnsupportedOperation(operation)
85    }
86}