polyc_embeddings/error.rs
1//! `EmbeddingError` marker trait and a reference implementation.
2//!
3//! Every `EmbeddingProvider::Error` associated type must satisfy the
4//! [`EmbeddingError`] bound, equivalent to
5//! `std::error::Error + Send + Sync + 'static` but named so it is grep-able and
6//! can grow cross-backend extension methods without breaking changes. Mirrors
7//! `polyc_llm::error::LlmError`.
8
9/// Marker trait that every `EmbeddingProvider::Error` must satisfy.
10///
11/// Equivalent to `std::error::Error + Send + Sync + 'static`, written as its
12/// own trait so it is searchable, a single place to add cross-backend
13/// extension methods later, and a sticky name in error messages.
14pub trait EmbeddingError: std::error::Error + Send + Sync + 'static {}
15
16/// Blanket impl: any type that meets the bound is an `EmbeddingError`.
17impl<T> EmbeddingError for T where T: std::error::Error + Send + Sync + 'static {}
18
19/// Reference implementation: the shape of error a real backend would ship.
20/// Concrete backend crates define their own.
21#[derive(Debug, thiserror::Error)]
22pub enum DummyError {
23 /// The model could not be loaded (missing/corrupt weights).
24 #[error("model load failed: {0}")]
25 Load(String),
26
27 /// Embedding a batch failed (e.g. tokenisation).
28 #[error("embed failed: {0}")]
29 Embed(String),
30
31 /// Anything else, escape hatch.
32 #[error("other: {0}")]
33 Other(String),
34}
35
36#[cfg(test)]
37mod tests {
38 use super::{DummyError, EmbeddingError};
39
40 fn require_embedding_error<E: EmbeddingError>() {}
41 fn assert_send_sync<T: Send + Sync + 'static>() {}
42
43 #[test]
44 fn display_load() {
45 let e = DummyError::Load("no safetensors".to_owned());
46 assert_eq!(format!("{e}"), "model load failed: no safetensors");
47 }
48
49 #[test]
50 fn dummy_error_satisfies_embedding_error() {
51 require_embedding_error::<DummyError>();
52 }
53
54 #[test]
55 fn dummy_error_is_send_sync_static() {
56 assert_send_sync::<DummyError>();
57 }
58}