#[cfg(feature = "alloc")]
#[allow(
unused_imports,
reason = "alloc prelude items; subset used per cfg/feature combination"
)]
use alloc::{format, string::ToString, vec, vec::Vec};
use thiserror::Error as ThisError;
#[derive(Debug, ThisError, PartialEq, Eq)]
pub enum Error {
#[error(
"Integer Overflow: The decoded Base64 value exceeds the maximum size for the target integer type."
)]
IntegerOverflow,
#[error(
"Invalid Base64 Character: Encountered '{0}', which is not part of the URL-safe Base64 character set."
)]
InvalidBase64Char(char),
#[error(
"Invalid Base64 Value: The value {0} is out of bounds for the Base64 character set (0-63)."
)]
InvalidBase64Value(u8),
#[error(
"Short Binary Stream: More bytes were expected to complete the parsing operation, but the stream ended."
)]
ShortBinaryStream,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn integer_overflow_display() {
let err = Error::IntegerOverflow;
let msg = err.to_string();
assert!(
msg.contains("Integer Overflow"),
"expected 'Integer Overflow' in: {msg}"
);
}
#[test]
fn invalid_base64_char_display_contains_char() {
let err = Error::InvalidBase64Char('+');
let msg = err.to_string();
assert!(msg.contains('+'), "expected '+' in: {msg}");
}
#[test]
fn invalid_base64_char_display_contains_label() {
let err = Error::InvalidBase64Char('!');
let msg = err.to_string();
assert!(
msg.contains("Invalid Base64 Character"),
"expected 'Invalid Base64 Character' in: {msg}"
);
}
#[test]
fn invalid_base64_value_display_contains_value() {
let err = Error::InvalidBase64Value(65);
let msg = err.to_string();
assert!(msg.contains("65"), "expected '65' in: {msg}");
}
#[test]
fn invalid_base64_value_display_contains_label() {
let err = Error::InvalidBase64Value(99);
let msg = err.to_string();
assert!(
msg.contains("Invalid Base64 Value"),
"expected 'Invalid Base64 Value' in: {msg}"
);
}
#[test]
fn short_binary_stream_display() {
let err = Error::ShortBinaryStream;
let msg = err.to_string();
assert!(
msg.contains("Short Binary Stream"),
"expected 'Short Binary Stream' in: {msg}"
);
}
#[test]
fn same_variants_are_equal() {
assert_eq!(Error::IntegerOverflow, Error::IntegerOverflow);
assert_eq!(Error::ShortBinaryStream, Error::ShortBinaryStream);
assert_eq!(Error::InvalidBase64Char('x'), Error::InvalidBase64Char('x'));
assert_eq!(Error::InvalidBase64Value(10), Error::InvalidBase64Value(10));
}
#[test]
fn different_payloads_are_not_equal() {
assert_ne!(Error::InvalidBase64Char('x'), Error::InvalidBase64Char('y'));
assert_ne!(Error::InvalidBase64Value(10), Error::InvalidBase64Value(11));
}
#[test]
fn different_variants_are_not_equal() {
assert_ne!(Error::IntegerOverflow, Error::ShortBinaryStream);
}
#[test]
fn error_debug_contains_variant_name() {
let cases: Vec<(&str, Error)> = vec![
("IntegerOverflow", Error::IntegerOverflow),
("InvalidBase64Char", Error::InvalidBase64Char('!')),
("InvalidBase64Value", Error::InvalidBase64Value(99)),
("ShortBinaryStream", Error::ShortBinaryStream),
];
for (expected_name, err) in cases {
let debug = format!("{err:?}");
assert!(
debug.contains(expected_name),
"expected '{expected_name}' in debug output: {debug}"
);
}
}
#[test]
fn error_implements_std_error() {
fn assert_std_error<T: core::error::Error>() {}
assert_std_error::<Error>();
}
}