use async_trait::async_trait;
use crate::analyzer::VisionError;
#[async_trait]
pub trait ImageEmbedder: Send + Sync {
async fn embed_image(&self, image: &[u8]) -> Result<Vec<f32>, VisionError>;
fn dimension(&self) -> usize;
fn name(&self) -> &str;
}
pub struct NoopEmbedder {
dim: usize,
}
impl NoopEmbedder {
pub fn new(dim: usize) -> Self {
Self { dim }
}
}
impl Default for NoopEmbedder {
fn default() -> Self {
Self::new(512)
}
}
#[async_trait]
impl ImageEmbedder for NoopEmbedder {
async fn embed_image(&self, image: &[u8]) -> Result<Vec<f32>, VisionError> {
if image.is_empty() {
return Err(VisionError::EmptyImage);
}
Err(VisionError::AnalysisFailed(
"no embedding backend configured".into(),
))
}
fn dimension(&self) -> usize {
self.dim
}
fn name(&self) -> &str {
"noop"
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_noop_embedder_empty() {
let e = NoopEmbedder::default();
let result = e.embed_image(b"").await;
assert!(matches!(result, Err(VisionError::EmptyImage)));
}
#[tokio::test]
async fn test_noop_embedder_dimension() {
let e = NoopEmbedder::new(768);
assert_eq!(e.dimension(), 768);
}
}