Skip to main content

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}