qubit_text_codec/error/charset_encode_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 encoding Unicode text into encoded units.
13#[derive(Clone, Copy, Debug, Eq, Error, PartialEq)]
14pub enum CharsetEncodeErrorKind {
15 /// The supplied code point is not a valid Unicode scalar value.
16 #[error("The code point is not a valid Unicode scalar value.")]
17 InvalidCodePoint {
18 /// Raw code point value reported by the codec.
19 value: u32,
20 },
21
22 /// The requested input character index is outside the input buffer.
23 #[error("The input character index is outside the input buffer.")]
24 InvalidInputIndex {
25 /// Length of the input provided to the codec call.
26 input_len: usize,
27 },
28
29 /// The character cannot be represented by the target encoding.
30 #[error("The character cannot be represented by the target encoding.")]
31 UnmappableCharacter {
32 /// Raw character value that cannot be represented.
33 value: u32,
34 },
35
36 /// The supplied output buffer is too small for the encoded character.
37 #[error("The output buffer is too small (required {required} units, available {available} units).")]
38 BufferTooSmall {
39 /// Total units required to encode the character.
40 required: usize,
41
42 /// Total units currently available for the requested output index.
43 available: usize,
44 },
45}
46
47impl CharsetEncodeErrorKind {
48 /// Returns the raw value associated with the error kind, if available.
49 ///
50 /// # Returns
51 ///
52 /// - `Some(value)` for [`Self::InvalidCodePoint`] and [`Self::UnmappableCharacter`];
53 /// - `None` for other kinds.
54 #[must_use]
55 #[inline]
56 pub const fn value(self) -> Option<u32> {
57 match self {
58 Self::InvalidCodePoint { value, .. } => Some(value),
59 Self::UnmappableCharacter { value, .. } => Some(value),
60 Self::BufferTooSmall { .. } | Self::InvalidInputIndex { .. } => None,
61 }
62 }
63
64 /// Returns the number of required output units for this kind, if available.
65 ///
66 /// # Returns
67 ///
68 /// - `Some(required)` for [`Self::BufferTooSmall`];
69 /// - `None` for all other variants.
70 #[must_use]
71 #[inline]
72 pub const fn required(self) -> Option<usize> {
73 match self {
74 Self::BufferTooSmall { required, .. } => Some(required),
75 Self::InvalidInputIndex { .. } | Self::InvalidCodePoint { .. } | Self::UnmappableCharacter { .. } => None,
76 }
77 }
78
79 /// Returns the number of currently available output units for this kind, if
80 /// available.
81 ///
82 /// # Returns
83 ///
84 /// - `Some(available)` for [`Self::BufferTooSmall`];
85 /// - `None` for all other variants.
86 #[must_use]
87 #[inline]
88 pub const fn available(self) -> Option<usize> {
89 match self {
90 Self::BufferTooSmall { available, .. } => Some(available),
91 Self::InvalidInputIndex { .. } | Self::InvalidCodePoint { .. } | Self::UnmappableCharacter { .. } => None,
92 }
93 }
94
95 /// Returns the input length when this error comes from an invalid input index.
96 ///
97 /// # Returns
98 ///
99 /// - `Some(input_len)` for [`Self::InvalidInputIndex`];
100 /// - `None` for other variants.
101 #[must_use]
102 #[inline]
103 pub const fn input_len(self) -> Option<usize> {
104 match self {
105 Self::InvalidInputIndex { input_len } => Some(input_len),
106 Self::InvalidCodePoint { .. } | Self::UnmappableCharacter { .. } | Self::BufferTooSmall { .. } => None,
107 }
108 }
109}