Skip to main content

stealth_lib/
error.rs

1//! Error types for stealth-lib operations.
2//!
3//! This module provides a unified error type for all operations in the library.
4//! All errors are typed and provide meaningful context for debugging.
5
6use core::fmt;
7
8/// All errors that can occur in stealth-lib operations.
9///
10/// This enum is `#[non_exhaustive]` to allow adding new variants in future
11/// minor versions without breaking semver compatibility.
12///
13/// # Example
14///
15/// ```
16/// use stealth_lib::Error;
17///
18/// fn example() -> Result<(), Error> {
19///     Err(Error::TreeFull {
20///         capacity: 1048576,
21///         attempted_index: 1048576,
22///     })
23/// }
24/// ```
25#[derive(Debug, Clone, PartialEq, Eq)]
26#[non_exhaustive]
27pub enum Error {
28    /// Merkle tree has reached maximum capacity.
29    ///
30    /// This occurs when attempting to insert a leaf into a full tree.
31    /// The tree capacity is `2^levels`.
32    TreeFull {
33        /// Maximum number of leaves the tree can hold.
34        capacity: usize,
35        /// The index that was attempted.
36        attempted_index: usize,
37    },
38
39    /// Invalid Merkle proof.
40    ///
41    /// The proof does not verify against the expected root.
42    InvalidProof,
43
44    /// Root not found in history.
45    ///
46    /// The provided root hash is not in the tree's root history buffer.
47    UnknownRoot,
48
49    /// Input data has invalid length.
50    ///
51    /// Expected a specific number of bytes but received a different amount.
52    InvalidLength {
53        /// Expected length in bytes.
54        expected: usize,
55        /// Actual length received.
56        actual: usize,
57    },
58
59    /// Parsing failed.
60    ///
61    /// Failed to parse input data (e.g., from string representation).
62    ParseError(String),
63
64    /// Arithmetic overflow in field operations.
65    ///
66    /// An arithmetic operation would overflow the field modulus.
67    FieldOverflow,
68
69    /// Invalid tree configuration.
70    ///
71    /// The tree parameters are invalid (e.g., zero levels).
72    InvalidTreeConfig(String),
73
74    /// Leaf index out of bounds.
75    ///
76    /// The requested leaf index does not exist in the tree.
77    LeafIndexOutOfBounds {
78        /// The requested index.
79        index: u32,
80        /// The current number of leaves in the tree.
81        tree_size: u32,
82    },
83}
84
85impl fmt::Display for Error {
86    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87        match self {
88            Error::TreeFull {
89                capacity,
90                attempted_index,
91            } => {
92                write!(
93                    f,
94                    "Merkle tree is full: capacity={}, attempted index={}",
95                    capacity, attempted_index
96                )
97            }
98            Error::InvalidProof => write!(f, "Invalid Merkle proof"),
99            Error::UnknownRoot => write!(f, "Root not found in history"),
100            Error::InvalidLength { expected, actual } => {
101                write!(
102                    f,
103                    "Invalid length: expected {} bytes, got {}",
104                    expected, actual
105                )
106            }
107            Error::ParseError(msg) => write!(f, "Parse error: {}", msg),
108            Error::FieldOverflow => write!(f, "Arithmetic overflow in field operation"),
109            Error::InvalidTreeConfig(msg) => write!(f, "Invalid tree configuration: {}", msg),
110            Error::LeafIndexOutOfBounds { index, tree_size } => {
111                write!(
112                    f,
113                    "Leaf index {} out of bounds (tree has {} leaves)",
114                    index, tree_size
115                )
116            }
117        }
118    }
119}
120
121#[cfg(feature = "std")]
122impl std::error::Error for Error {}
123
124/// Result type alias for stealth-lib operations.
125///
126/// This is a convenience alias that uses [`Error`] as the error type.
127///
128/// # Example
129///
130/// ```
131/// use stealth_lib::{Result, MerkleTree};
132///
133/// fn insert_leaf(tree: &mut MerkleTree, leaf: u128) -> Result<u32> {
134///     tree.insert(leaf)
135/// }
136/// ```
137pub type Result<T> = core::result::Result<T, Error>;
138
139#[cfg(test)]
140mod tests {
141    use super::*;
142
143    #[test]
144    fn test_error_display() {
145        let err = Error::TreeFull {
146            capacity: 100,
147            attempted_index: 100,
148        };
149        assert!(err.to_string().contains("100"));
150
151        let err = Error::ParseError("invalid input".to_string());
152        assert!(err.to_string().contains("invalid input"));
153    }
154
155    #[test]
156    fn test_error_equality() {
157        let err1 = Error::InvalidProof;
158        let err2 = Error::InvalidProof;
159        assert_eq!(err1, err2);
160
161        let err3 = Error::UnknownRoot;
162        assert_ne!(err1, err3);
163    }
164}