Skip to main content

qubit_text_codec/error/
charset_encode_error.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 core::fmt;
11use std::error::Error;
12
13use crate::{
14    Charset,
15    CharsetEncodeErrorKind,
16};
17
18/// Error reported by a charset encoder.
19///
20/// The error always carries the target charset, error kind, and operation
21/// index associated with the failure. For buffer errors this is the caller-supplied
22/// output index. Errors tied to a raw code point or character value expose that
23/// value through [`Self::kind`] and [`Self::value`].
24#[derive(Clone, Copy, Debug, Eq, PartialEq)]
25pub struct CharsetEncodeError {
26    /// Target charset of the operation that produced this error.
27    charset: Charset,
28    /// Failure category describing why encoding could not proceed.
29    kind: CharsetEncodeErrorKind,
30    /// Output unit index or input code point index where failure occurred.
31    index: usize,
32}
33
34/// Result type returned by charset encoders.
35///
36/// # Type Parameters
37///
38/// - `T`: Successful value produced by an encoding operation.
39pub type CharsetEncodeResult<T> = Result<T, CharsetEncodeError>;
40
41impl CharsetEncodeError {
42    /// Creates an encoding error.
43    ///
44    /// # Parameters
45    ///
46    /// - `charset`: The target charset.
47    /// - `kind`: The failure category.
48    /// - `index`: The operation index associated with the failure.
49    ///
50    /// # Returns
51    ///
52    /// Returns an encoding error carrying the supplied context.
53    #[inline]
54    pub const fn new(charset: Charset, kind: CharsetEncodeErrorKind, index: usize) -> Self {
55        Self { charset, kind, index }
56    }
57
58    /// Returns required output units for this encoding error, if reported.
59    ///
60    /// # Returns
61    ///
62    /// Returns `Some(required)` for [`CharsetEncodeErrorKind::BufferTooSmall`],
63    /// otherwise `None`.
64    #[inline]
65    pub const fn required(self) -> Option<usize> {
66        self.kind.required()
67    }
68
69    /// Returns available output units for this encoding error, if reported.
70    ///
71    /// # Returns
72    ///
73    /// Returns `Some(available)` for [`CharsetEncodeErrorKind::BufferTooSmall`],
74    /// otherwise `None`.
75    #[inline]
76    pub const fn available(self) -> Option<usize> {
77        self.kind.available()
78    }
79
80    /// Returns the target charset.
81    ///
82    /// # Returns
83    ///
84    /// Returns the stored [`Charset`].
85    #[inline]
86    pub const fn charset(self) -> Charset {
87        self.charset
88    }
89
90    /// Returns the encoding error kind.
91    ///
92    /// # Returns
93    ///
94    /// Returns the stored [`CharsetEncodeErrorKind`].
95    #[inline]
96    pub const fn kind(self) -> CharsetEncodeErrorKind {
97        self.kind
98    }
99
100    /// Returns the operation index associated with this error.
101    ///
102    /// # Returns
103    ///
104    /// Returns the stored index.
105    #[inline]
106    pub const fn index(self) -> usize {
107        self.index
108    }
109
110    /// Returns the raw value associated with this error.
111    ///
112    /// # Returns
113    ///
114    /// Returns `Some(value)` when the error kind carries a raw code point or
115    /// character value, or `None` for kinds without an associated value.
116    #[inline]
117    pub const fn value(self) -> Option<u32> {
118        self.kind.value()
119    }
120
121    /// Offsets this error by a base unit index.
122    ///
123    /// # Parameters
124    ///
125    /// - `base`: The base index to add to the stored index.
126    ///
127    /// # Returns
128    ///
129    /// Returns a copy of this error with its index shifted by `base`.
130    #[inline]
131    pub const fn offset_by(self, base: usize) -> Self {
132        Self {
133            charset: self.charset,
134            kind: self.kind,
135            index: self.index + base,
136        }
137    }
138}
139
140impl fmt::Display for CharsetEncodeError {
141    /// Formats this encoding error.
142    ///
143    /// # Parameters
144    ///
145    /// - `formatter`: The formatter receiving the diagnostic message.
146    ///
147    /// # Errors
148    ///
149    /// Returns any formatting error reported by `formatter`.
150    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
151        if let Some(value) = self.kind.value() {
152            write!(
153                formatter,
154                "{} encoding error at index {} for value 0x{:x}: {}",
155                self.charset, self.index, value, self.kind,
156            )
157        } else {
158            write!(
159                formatter,
160                "{} encoding error at index {}: {}",
161                self.charset, self.index, self.kind,
162            )
163        }
164    }
165}
166
167impl Error for CharsetEncodeError {}