pub mod ai; pub mod pure; pub mod vecmetric; pub(crate) use ai::*; pub(crate) use pure::*; pub(crate) use vecmetric::*; use anyhow::Result; use indicatif::{ParallelProgressIterator, ProgressStyle}; use rayon::prelude::*; use serde::{Deserialize, Serialize}; use std::path::{Path, PathBuf}; pub trait MetricElem: Send + Sync + 'static + Serialize + for<'a> Deserialize<'a> { fn dist(&self, _: &Self) -> f64; } impl MetricElem for f64 { fn dist(&self, b: &f64) -> f64 { (self - b).abs() } } pub trait EmbedderT: Send + Sync { type Embedding: MetricElem; const NAME: &'static str; fn embed(&self, _: &Path) -> Result; } pub trait BatchEmbedder: Send + Sync { type Embedding: MetricElem; const NAME: &'static str; fn embeds(&mut self, _: &[PathBuf]) -> Result>; } impl BatchEmbedder for T { type Embedding = T::Embedding; const NAME: &'static str = T::NAME; fn embeds(&mut self, paths: &[PathBuf]) -> Result> { let st = ProgressStyle::with_template("{bar:20.cyan/blue} {pos}/{len} Embedding images...")?; paths .par_iter() .progress_with_style(st) .map(|p| self.embed(p)) .collect::>() .into_iter() .try_collect() } }