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}