Skip to main content

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}