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 {}