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}