#[cfg(feature = "vector-memory")]
pub mod hash_embedder;
#[cfg(feature = "vector-memory")]
pub mod hnsw_store;
#[cfg(feature = "vector-memory")]
pub mod micro_hnsw;
#[cfg(feature = "rvf")]
pub mod api_embedder;
#[cfg(feature = "rvf")]
pub mod progressive;
#[cfg(feature = "rvf")]
pub mod quantization;
#[cfg(feature = "rvf")]
pub mod rvf_io;
#[cfg(feature = "rvf")]
pub mod rvf_stub;
#[cfg(feature = "rvf")]
pub mod witness;
use async_trait::async_trait;
use std::fmt;
#[non_exhaustive]
#[derive(Debug)]
pub enum EmbeddingError {
InvalidInput(String),
Internal(String),
}
impl fmt::Display for EmbeddingError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EmbeddingError::InvalidInput(msg) => write!(f, "invalid input: {msg}"),
EmbeddingError::Internal(msg) => write!(f, "internal error: {msg}"),
}
}
}
impl std::error::Error for EmbeddingError {}
#[async_trait]
pub trait Embedder: Send + Sync {
async fn embed(&self, text: &str) -> Result<Vec<f32>, EmbeddingError>;
async fn embed_batch(&self, texts: &[String]) -> Result<Vec<Vec<f32>>, EmbeddingError> {
let mut results = Vec::with_capacity(texts.len());
for text in texts {
results.push(self.embed(text).await?);
}
Ok(results)
}
fn dimension(&self) -> usize;
fn name(&self) -> &str {
"unknown"
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn embedding_error_display_invalid_input() {
let err = EmbeddingError::InvalidInput("bad text".into());
assert_eq!(format!("{err}"), "invalid input: bad text");
}
#[test]
fn embedding_error_display_internal() {
let err = EmbeddingError::Internal("something broke".into());
assert_eq!(format!("{err}"), "internal error: something broke");
}
#[test]
fn embedding_error_is_error_trait() {
let err: Box<dyn std::error::Error> = Box::new(EmbeddingError::Internal("test".into()));
assert!(err.to_string().contains("test"));
}
}