use anyhow::Result; use rayon::prelude::*; use std::path::{Path, PathBuf}; use serde::{Deserialize, Serialize}; 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> { paths.par_iter() .map(|p| self.embed(p)) .collect::>() .into_iter() .try_collect() } }