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}