Skip to main content

multi_trait/
error.rs

1// SPDX-License-Identifier: Apache-2.0
2
3#[cfg(not(feature = "std"))]
4use alloc::string::String;
5
6/// Errors generated by the numeric type impls
7///
8/// This error type follows Rust error handling best practices:
9/// - Uses `#[non_exhaustive]` to allow adding new variants without breaking changes
10/// - Provides structured error variants with context information
11/// - Implements proper error source chains via `#[source]` attribute
12/// - Uses `thiserror` for ergonomic error handling
13///
14/// # Error Source Chains
15///
16/// Errors that wrap other errors (like `UnsignedVarintDecode`) properly implement
17/// the `Error::source()` method, allowing error chains to be inspected for debugging.
18///
19/// # Examples
20///
21/// ```
22/// use multi_trait::{TryDecodeFrom, Error};
23///
24/// // Attempting to decode from empty slice returns an error
25/// let result = u8::try_decode_from(&[]);
26/// assert!(result.is_err());
27///
28/// // The error provides context about what went wrong
29/// if let Err(e) = result {
30///     eprintln!("Decode failed: {}", e);
31///     // In production code with std, you can access the error source:
32///     // if let Some(source) = std::error::Error::source(&e) {
33///     //     eprintln!("Caused by: {}", source);
34///     // }
35/// }
36/// ```
37#[derive(Debug, thiserror::Error)]
38#[non_exhaustive]
39pub enum Error {
40    /// Failed to decode unsigned varint data
41    ///
42    /// This error occurs when the underlying unsigned-varint decoder fails.
43    /// Common causes include:
44    /// - Truncated varint data (incomplete bytes)
45    /// - Invalid varint encoding
46    /// - Buffer underflow
47    ///
48    /// The source error provides additional details about the specific failure.
49    #[cfg(feature = "std")]
50    #[error("failed to decode unsigned varint")]
51    UnsignedVarintDecode {
52        /// The underlying decode error from unsigned-varint crate
53        #[source]
54        source: unsigned_varint::decode::Error,
55    },
56
57    /// Failed to decode unsigned varint data (no_std variant)
58    ///
59    /// This error occurs when the underlying unsigned-varint decoder fails.
60    /// Common causes include:
61    /// - Truncated varint data (incomplete bytes)
62    /// - Invalid varint encoding
63    /// - Buffer underflow
64    #[cfg(not(feature = "std"))]
65    #[error("failed to decode unsigned varint: {message}")]
66    UnsignedVarintDecode {
67        /// Error message from the underlying decoder
68        message: String,
69    },
70
71    /// Insufficient data to decode value
72    ///
73    /// This error occurs when the input slice doesn't contain enough bytes
74    /// to decode the requested type. This typically happens with truncated data.
75    ///
76    /// # Examples
77    ///
78    /// ```
79    /// use multi_trait::{TryDecodeFrom, Error};
80    ///
81    /// // Empty slice cannot decode any value
82    /// let result = u16::try_decode_from(&[]);
83    /// match result {
84    ///     Err(Error::UnsignedVarintDecode { .. }) => {
85    ///         // Expected behavior for empty input
86    ///     }
87    ///     _ => panic!("Unexpected result"),
88    /// }
89    /// ```
90    #[error("insufficient data: expected at least {expected} bytes, found {actual}")]
91    InsufficientData {
92        /// Expected number of bytes needed
93        expected: usize,
94        /// Actual number of bytes available in the input
95        actual: usize,
96    },
97
98    /// Invalid encoding encountered
99    ///
100    /// This error occurs when the data is structurally invalid beyond just
101    /// varint decoding issues. For example, if a value is out of range for
102    /// the target type or violates format-specific constraints.
103    ///
104    /// This variant is provided for future extensibility and custom
105    /// validation logic.
106    #[error("invalid encoding: {reason}")]
107    InvalidEncoding {
108        /// Human-readable description of why the encoding is invalid
109        reason: String,
110    },
111}