Skip to main content

qubit_text_codec/error/
charset_decode_error_kind.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10use thiserror::Error;
11
12/// Classifies failures detected while decoding encoded units into Unicode text.
13#[derive(Clone, Copy, Debug, Eq, Error, PartialEq)]
14pub enum CharsetDecodeErrorKind {
15    /// The input units do not form a well-formed encoded sequence.
16    #[error("The encoded text sequence is malformed.")]
17    MalformedSequence {
18        /// Optional malformed raw value captured from the offending input unit.
19        value: Option<u32>,
20    },
21
22    /// The closed input ended before a complete character was available.
23    #[error("The encoded text sequence is incomplete (required {required} units, available {available} units).")]
24    IncompleteSequence {
25        /// Total units required to complete the current sequence.
26        required: usize,
27
28        /// Total units currently available from the start of the current sequence.
29        available: usize,
30    },
31
32    /// The decoded numeric value is not a valid Unicode scalar value.
33    #[error("The decoded code point 0x{value:x} is not a valid Unicode scalar value.")]
34    InvalidCodePoint {
35        /// Raw decoded code-point value.
36        value: u32,
37    },
38}
39
40impl CharsetDecodeErrorKind {
41    /// Returns the number of required input units for this kind, if available.
42    ///
43    /// # Returns
44    ///
45    /// - `Some(required)` for [`Self::IncompleteSequence`];
46    /// - `None` for all other variants.
47    #[must_use]
48    #[inline]
49    pub const fn required(self) -> Option<usize> {
50        match self {
51            Self::IncompleteSequence { required, .. } => Some(required),
52            Self::MalformedSequence { .. } | Self::InvalidCodePoint { .. } => None,
53        }
54    }
55
56    /// Returns the number of currently available input units for this kind, if
57    /// available.
58    ///
59    /// # Returns
60    ///
61    /// - `Some(available)` for [`Self::IncompleteSequence`];
62    /// - `None` for all other variants.
63    #[must_use]
64    #[inline]
65    pub const fn available(self) -> Option<usize> {
66        match self {
67            Self::IncompleteSequence { available, .. } => Some(available),
68            Self::MalformedSequence { .. } | Self::InvalidCodePoint { .. } => None,
69        }
70    }
71
72    /// Returns the raw malformed value associated with this decoding error, if any.
73    ///
74    /// # Returns
75    ///
76    /// - `Some(value)` for [`Self::MalformedSequence`] when a specific malformed
77    ///   unit value is available.
78    /// - `Some(value)` for [`Self::InvalidCodePoint`].
79    /// - `None` for other variants.
80    #[must_use]
81    #[inline]
82    pub const fn value(self) -> Option<u32> {
83        match self {
84            Self::MalformedSequence { value } => value,
85            Self::InvalidCodePoint { value } => Some(value),
86            Self::IncompleteSequence { .. } => None,
87        }
88    }
89}