1use thiserror::Error;
11
12use super::{
13 capacity_error::CapacityError,
14 transcode_decode_error::TranscodeDecodeError,
15 transcode_domain_error::TranscodeDomainError,
16 transcode_encode_error::TranscodeEncodeError,
17 transcode_failure::TranscodeFailure,
18};
19use crate::Codec;
20
21pub type TranscodeConvertErrorOf<D, E> = TranscodeConvertError<
23 <D as Codec>::DecodeError,
24 <E as Codec>::EncodeError,
25 <D as Codec>::Value,
26>;
27
28#[derive(Clone, Debug, Eq, Error, Hash, PartialEq)]
30pub enum TranscodeConvertError<DE, EE, V> {
31 #[error(transparent)]
33 Failure(#[from] TranscodeFailure),
34
35 #[error("decode side failed: {0}")]
37 DecodeDomain(#[source] TranscodeDomainError<DE>),
38
39 #[error("encode side failed: {0}")]
41 EncodeDomain(#[source] TranscodeDomainError<EE>),
42
43 #[error("unencodable value at input index {input_index}")]
46 Unencodable {
47 input_index: usize,
49 value: Option<V>,
51 },
52}
53
54impl<DE, EE, V> TranscodeConvertError<DE, EE, V> {
55 #[inline(always)]
57 pub const fn decode_domain_reset(source: DE) -> Self {
58 Self::DecodeDomain(TranscodeDomainError::reset(source))
59 }
60
61 #[inline(always)]
63 pub const fn decode_domain_main(source: DE, input_index: usize) -> Self {
64 Self::DecodeDomain(TranscodeDomainError::main(source, input_index))
65 }
66
67 #[inline(always)]
70 pub const fn decode_domain_main_with_consumed(
71 source: DE,
72 input_index: usize,
73 input_consumed: Option<core::num::NonZeroUsize>,
74 ) -> Self {
75 Self::DecodeDomain(TranscodeDomainError::main_with_consumed(
76 source,
77 input_index,
78 input_consumed,
79 ))
80 }
81
82 #[inline(always)]
84 pub const fn decode_domain_finish(source: DE) -> Self {
85 Self::DecodeDomain(TranscodeDomainError::finish(source))
86 }
87
88 #[inline(always)]
90 pub const fn encode_domain_reset(source: EE) -> Self {
91 Self::EncodeDomain(TranscodeDomainError::reset(source))
92 }
93
94 #[inline(always)]
96 pub const fn encode_domain_main(source: EE, input_index: usize) -> Self {
97 Self::EncodeDomain(TranscodeDomainError::main(source, input_index))
98 }
99
100 #[inline(always)]
102 pub const fn encode_domain_finish(source: EE) -> Self {
103 Self::EncodeDomain(TranscodeDomainError::finish(source))
104 }
105
106 #[inline(always)]
108 #[must_use]
109 pub fn unencodable(input_index: usize, value: V) -> Self {
110 Self::Unencodable {
111 input_index,
112 value: Some(value),
113 }
114 }
115
116 #[inline(always)]
118 #[must_use]
119 pub const fn unencodable_without_context(input_index: usize) -> Self {
120 Self::Unencodable {
121 input_index,
122 value: None,
123 }
124 }
125
126 #[inline(always)]
128 #[must_use]
129 pub const fn failure_ref(&self) -> Option<&TranscodeFailure> {
130 match self {
131 Self::Failure(failure) => Some(failure),
132 Self::DecodeDomain(_)
133 | Self::EncodeDomain(_)
134 | Self::Unencodable { .. } => None,
135 }
136 }
137
138 #[inline(always)]
140 #[must_use]
141 pub const fn unencodable_ref(&self) -> Option<(usize, Option<&V>)> {
142 match self {
143 Self::Unencodable { input_index, value } => {
144 Some((*input_index, value.as_ref()))
145 }
146 Self::Failure(_)
147 | Self::DecodeDomain(_)
148 | Self::EncodeDomain(_) => None,
149 }
150 }
151
152 #[inline]
154 pub fn map_decode_domain<F, T>(
155 self,
156 f: F,
157 ) -> TranscodeConvertError<T, EE, V>
158 where
159 F: FnOnce(DE) -> T,
160 {
161 match self {
162 Self::Failure(failure) => TranscodeConvertError::Failure(failure),
163 Self::DecodeDomain(error) => {
164 TranscodeConvertError::DecodeDomain(error.map_source(f))
165 }
166 Self::EncodeDomain(error) => {
167 TranscodeConvertError::EncodeDomain(error)
168 }
169 Self::Unencodable { input_index, value } => {
170 TranscodeConvertError::Unencodable { input_index, value }
171 }
172 }
173 }
174
175 #[inline]
177 pub fn map_encode_domain<F, T>(
178 self,
179 f: F,
180 ) -> TranscodeConvertError<DE, T, V>
181 where
182 F: FnOnce(EE) -> T,
183 {
184 match self {
185 Self::Failure(failure) => TranscodeConvertError::Failure(failure),
186 Self::DecodeDomain(error) => {
187 TranscodeConvertError::DecodeDomain(error)
188 }
189 Self::EncodeDomain(error) => {
190 TranscodeConvertError::EncodeDomain(error.map_source(f))
191 }
192 Self::Unencodable { input_index, value } => {
193 TranscodeConvertError::Unencodable { input_index, value }
194 }
195 }
196 }
197
198 #[inline]
200 pub fn map_value<F, W>(self, f: F) -> TranscodeConvertError<DE, EE, W>
201 where
202 F: FnOnce(V) -> W,
203 {
204 match self {
205 Self::Failure(failure) => TranscodeConvertError::Failure(failure),
206 Self::DecodeDomain(error) => {
207 TranscodeConvertError::DecodeDomain(error)
208 }
209 Self::EncodeDomain(error) => {
210 TranscodeConvertError::EncodeDomain(error)
211 }
212 Self::Unencodable { input_index, value } => {
213 TranscodeConvertError::Unencodable {
214 input_index,
215 value: value.map(f),
216 }
217 }
218 }
219 }
220
221 #[inline]
224 pub fn from_encode_error_with_value(
225 error: TranscodeEncodeError<EE, V>,
226 fallback_value: V,
227 ) -> Self {
228 match error {
229 TranscodeEncodeError::Unencodable {
230 input_index,
231 value: None,
232 } => Self::Unencodable {
233 input_index,
234 value: Some(fallback_value),
235 },
236 other => Self::from(other),
237 }
238 }
239}
240
241impl<DE, EE, V> From<TranscodeDecodeError<DE>>
242 for TranscodeConvertError<DE, EE, V>
243{
244 #[inline]
246 fn from(error: TranscodeDecodeError<DE>) -> Self {
247 match error {
248 TranscodeDecodeError::Failure(failure) => Self::Failure(failure),
249 TranscodeDecodeError::Domain(error) => Self::DecodeDomain(error),
250 }
251 }
252}
253
254impl<DE, EE, V> From<TranscodeEncodeError<EE, V>>
255 for TranscodeConvertError<DE, EE, V>
256{
257 #[inline]
259 fn from(error: TranscodeEncodeError<EE, V>) -> Self {
260 match error {
261 TranscodeEncodeError::Failure(failure) => Self::Failure(failure),
262 TranscodeEncodeError::Unencodable { input_index, value } => {
263 Self::Unencodable { input_index, value }
264 }
265 TranscodeEncodeError::Domain(error) => Self::EncodeDomain(error),
266 }
267 }
268}
269
270impl<DE, EE, V> From<CapacityError> for TranscodeConvertError<DE, EE, V> {
271 #[inline(always)]
273 fn from(error: CapacityError) -> Self {
274 TranscodeFailure::from(error).into()
275 }
276}