Skip to main content

qubit_codec_text/error/
charset_encode_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// =============================================================================
8use thiserror::Error;
9
10/// Classifies failures detected while encoding Unicode text into encoded units.
11#[derive(Clone, Copy, Debug, Eq, Error, PartialEq)]
12pub enum CharsetEncodeErrorKind {
13    /// The supplied code point is not a valid Unicode scalar value.
14    #[error("The code point is not a valid Unicode scalar value.")]
15    InvalidCodePoint {
16        /// Raw code point value reported by the codec.
17        value: u32,
18    },
19
20    /// The requested input character index is outside the input buffer.
21    #[error("The input character index is outside the input buffer.")]
22    InvalidInputIndex {
23        /// Length of the input provided to the codec call.
24        input_len: usize,
25    },
26
27    /// The requested output unit index is outside the output buffer.
28    #[error("The output unit index is outside the output buffer.")]
29    InvalidOutputIndex {
30        /// Length of the output provided to the codec call.
31        output_len: usize,
32    },
33
34    /// The character cannot be represented by the target encoding.
35    #[error("The character cannot be represented by the target encoding.")]
36    UnmappableCharacter {
37        /// Raw character value that cannot be represented.
38        value: u32,
39    },
40
41    /// The supplied output buffer is too small for the encoded character.
42    #[error(
43        "The output buffer is too small (required {required} units, available {available} units)."
44    )]
45    BufferTooSmall {
46        /// Total units required to encode the character.
47        required: usize,
48
49        /// Total units currently available for the requested output index.
50        available: usize,
51    },
52}
53
54impl CharsetEncodeErrorKind {
55    /// Returns the raw value associated with the error kind, if available.
56    ///
57    /// # Returns
58    ///
59    /// - `Some(value)` for [`Self::InvalidCodePoint`] and
60    ///   [`Self::UnmappableCharacter`];
61    /// - `None` for other kinds.
62    #[must_use]
63    #[inline(always)]
64    pub const fn value(self) -> Option<u32> {
65        match self {
66            Self::InvalidCodePoint { value, .. } => Some(value),
67            Self::UnmappableCharacter { value, .. } => Some(value),
68            Self::BufferTooSmall { .. }
69            | Self::InvalidInputIndex { .. }
70            | Self::InvalidOutputIndex { .. } => None,
71        }
72    }
73
74    /// Returns the number of required output units for this kind, if available.
75    ///
76    /// # Returns
77    ///
78    /// - `Some(required)` for [`Self::BufferTooSmall`];
79    /// - `None` for all other variants.
80    #[must_use]
81    #[inline(always)]
82    pub const fn required(self) -> Option<usize> {
83        match self {
84            Self::BufferTooSmall { required, .. } => Some(required),
85            Self::InvalidInputIndex { .. }
86            | Self::InvalidOutputIndex { .. }
87            | Self::InvalidCodePoint { .. }
88            | Self::UnmappableCharacter { .. } => None,
89        }
90    }
91
92    /// Returns the number of currently available output units for this kind, if
93    /// available.
94    ///
95    /// # Returns
96    ///
97    /// - `Some(available)` for [`Self::BufferTooSmall`];
98    /// - `None` for all other variants.
99    #[must_use]
100    #[inline(always)]
101    pub const fn available(self) -> Option<usize> {
102        match self {
103            Self::BufferTooSmall { available, .. } => Some(available),
104            Self::InvalidInputIndex { .. }
105            | Self::InvalidOutputIndex { .. }
106            | Self::InvalidCodePoint { .. }
107            | Self::UnmappableCharacter { .. } => None,
108        }
109    }
110
111    /// Returns the input length when this error comes from an invalid input
112    /// index.
113    ///
114    /// # Returns
115    ///
116    /// - `Some(input_len)` for [`Self::InvalidInputIndex`];
117    /// - `None` for other variants.
118    #[must_use]
119    #[inline(always)]
120    pub const fn input_len(self) -> Option<usize> {
121        match self {
122            Self::InvalidInputIndex { input_len } => Some(input_len),
123            Self::InvalidCodePoint { .. }
124            | Self::UnmappableCharacter { .. }
125            | Self::BufferTooSmall { .. }
126            | Self::InvalidOutputIndex { .. } => None,
127        }
128    }
129
130    /// Returns the output length when this error comes from an invalid output
131    /// index.
132    ///
133    /// # Returns
134    ///
135    /// - `Some(output_len)` for [`Self::InvalidOutputIndex`];
136    /// - `None` for other variants.
137    #[must_use]
138    #[inline(always)]
139    pub const fn output_len(self) -> Option<usize> {
140        match self {
141            Self::InvalidOutputIndex { output_len } => Some(output_len),
142            Self::InvalidCodePoint { .. }
143            | Self::InvalidInputIndex { .. }
144            | Self::UnmappableCharacter { .. }
145            | Self::BufferTooSmall { .. } => None,
146        }
147    }
148}