ruvector_sparsifier/error.rs
1//! Error types for the spectral graph sparsifier.
2//!
3//! All fallible operations in this crate return [`SparsifierError`] wrapped
4//! in the crate-level [`Result`] alias.
5
6use thiserror::Error;
7
8/// Convenience result alias for sparsifier operations.
9pub type Result<T> = std::result::Result<T, SparsifierError>;
10
11/// Errors that can occur during sparsification.
12#[derive(Error, Debug)]
13pub enum SparsifierError {
14 /// A vertex index was out of range for the current graph.
15 #[error("vertex {0} is out of bounds (graph has {1} vertices)")]
16 VertexOutOfBounds(usize, usize),
17
18 /// An edge between the given vertices was not found.
19 #[error("edge ({0}, {1}) not found")]
20 EdgeNotFound(usize, usize),
21
22 /// An edge between the given vertices already exists.
23 #[error("edge ({0}, {1}) already exists")]
24 EdgeAlreadyExists(usize, usize),
25
26 /// An edge weight was non-positive or non-finite.
27 #[error("invalid edge weight {0}: must be positive and finite")]
28 InvalidWeight(f64),
29
30 /// The epsilon parameter was out of the valid range `(0, 1)`.
31 #[error("invalid epsilon {0}: must be in (0, 1)")]
32 InvalidEpsilon(f64),
33
34 /// The edge budget was too small for the given graph.
35 #[error("edge budget {budget} is too small for {vertices} vertices (minimum {minimum})")]
36 BudgetTooSmall {
37 /// Requested budget.
38 budget: usize,
39 /// Number of vertices.
40 vertices: usize,
41 /// Minimum budget for this graph size.
42 minimum: usize,
43 },
44
45 /// The graph has no vertices; sparsification is undefined.
46 #[error("cannot sparsify an empty graph")]
47 EmptyGraph,
48
49 /// A spectral audit detected unacceptable distortion.
50 #[error("spectral audit failed: max relative error {max_error:.4} exceeds threshold {threshold:.4}")]
51 AuditFailed {
52 /// Observed maximum relative error.
53 max_error: f64,
54 /// Acceptable threshold.
55 threshold: f64,
56 },
57
58 /// An internal numerical error (e.g. NaN or overflow).
59 #[error("numerical error: {0}")]
60 Numerical(String),
61
62 /// Catch-all for unexpected internal errors.
63 #[error("internal error: {0}")]
64 Internal(String),
65}