Skip to main content

qubit_codec_misc/
base64_error_kind.rs

1// =============================================================================
2//    Copyright (c) 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Structured Base64 dependency error categories.
9
10use ::base64::DecodeError;
11
12/// Structured category for an error reported by the Base64 dependency.
13///
14/// # Examples
15///
16/// ```
17/// use qubit_codec_misc::Base64ErrorKind;
18///
19/// let kind = Base64ErrorKind::InvalidPadding;
20/// assert_eq!(kind, Base64ErrorKind::InvalidPadding);
21/// ```
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23#[must_use]
24pub enum Base64ErrorKind {
25    /// A byte outside the configured alphabet was encountered.
26    InvalidByte,
27    /// The number of Base64 symbols is invalid.
28    InvalidLength,
29    /// The final symbol contains bits that would be discarded.
30    InvalidLastSymbol,
31    /// Padding is absent, unexpected, or malformed for the configured engine.
32    InvalidPadding,
33}
34
35impl Base64ErrorKind {
36    /// Classifies a Base64 dependency error without discarding its source.
37    ///
38    /// # Parameters
39    ///
40    /// * `error` is the decoding error whose category is classified.
41    #[inline]
42    pub(crate) const fn from_decode_error(error: &DecodeError) -> Self {
43        match error {
44            DecodeError::InvalidByte(_, _) => Self::InvalidByte,
45            DecodeError::InvalidLength(_) => Self::InvalidLength,
46            DecodeError::InvalidLastSymbol { .. } => Self::InvalidLastSymbol,
47            DecodeError::InvalidPadding => Self::InvalidPadding,
48        }
49    }
50
51    /// Returns the input offset carried by this Base64 error, when available.
52    ///
53    /// # Parameters
54    ///
55    /// * `error` is the decoding error to inspect.
56    #[inline]
57    pub(crate) const fn input_index(error: &DecodeError) -> Option<usize> {
58        match error {
59            DecodeError::InvalidByte(index, _) | DecodeError::InvalidLastSymbol { offset: index, .. } => Some(*index),
60            DecodeError::InvalidLength(_) | DecodeError::InvalidPadding => None,
61        }
62    }
63
64    /// Returns the invalid symbol carried by this Base64 error, when present.
65    ///
66    /// # Parameters
67    ///
68    /// * `error` is the decoding error to inspect.
69    #[inline]
70    pub(crate) const fn symbol(error: &DecodeError) -> Option<u8> {
71        match error {
72            DecodeError::InvalidByte(_, symbol) | DecodeError::InvalidLastSymbol { symbol, .. } => Some(*symbol),
73            DecodeError::InvalidLength(_) | DecodeError::InvalidPadding => None,
74        }
75    }
76
77    /// Returns the invalid input length carried by this Base64 error, when
78    /// present.
79    ///
80    /// # Parameters
81    ///
82    /// * `error` is the decoding error to inspect.
83    #[inline]
84    pub(crate) const fn input_length(error: &DecodeError) -> Option<usize> {
85        match error {
86            DecodeError::InvalidLength(length) => Some(*length),
87            DecodeError::InvalidByte(_, _) | DecodeError::InvalidLastSymbol { .. } | DecodeError::InvalidPadding => {
88                None
89            }
90        }
91    }
92}