1use thiserror::Error;
11
12use super::capacity_error::CapacityError;
13use super::transcode_decode_error::TranscodeDecodeError;
14use super::transcode_domain_error::TranscodeDomainError;
15use super::transcode_encode_error::TranscodeEncodeError;
16use super::transcode_failure::TranscodeFailure;
17use crate::Codec;
18
19pub type TranscodeConvertErrorOf<D, E> =
21 TranscodeConvertError<<D as Codec>::DecodeError, <E as Codec>::EncodeError, <D as Codec>::Value>;
22
23#[derive(Clone, Debug, Eq, Error, Hash, PartialEq)]
25pub enum TranscodeConvertError<DE, EE, V> {
26 #[error(transparent)]
28 Failure(#[from] TranscodeFailure),
29
30 #[error("decode side failed: {0}")]
32 DecodeDomain(#[source] TranscodeDomainError<DE>),
33
34 #[error("encode side failed: {0}")]
36 EncodeDomain(#[source] TranscodeDomainError<EE>),
37
38 #[error("unencodable value at input index {input_index}")]
41 Unencodable {
42 input_index: usize,
44 value: Option<V>,
46 },
47}
48
49impl<DE, EE, V> TranscodeConvertError<DE, EE, V> {
50 #[inline(always)]
52 pub const fn decode_domain_reset(source: DE) -> Self {
53 Self::DecodeDomain(TranscodeDomainError::reset(source))
54 }
55
56 #[inline(always)]
58 pub const fn decode_domain_main(source: DE, input_index: usize) -> Self {
59 Self::DecodeDomain(TranscodeDomainError::main(source, input_index))
60 }
61
62 #[inline(always)]
65 pub const fn decode_domain_main_with_consumed(
66 source: DE,
67 input_index: usize,
68 input_consumed: Option<core::num::NonZeroUsize>,
69 ) -> Self {
70 Self::DecodeDomain(TranscodeDomainError::main_with_consumed(
71 source,
72 input_index,
73 input_consumed,
74 ))
75 }
76
77 #[inline(always)]
79 pub const fn decode_domain_finish(source: DE) -> Self {
80 Self::DecodeDomain(TranscodeDomainError::finish(source))
81 }
82
83 #[inline(always)]
85 pub const fn encode_domain_reset(source: EE) -> Self {
86 Self::EncodeDomain(TranscodeDomainError::reset(source))
87 }
88
89 #[inline(always)]
91 pub const fn encode_domain_main(source: EE, input_index: usize) -> Self {
92 Self::EncodeDomain(TranscodeDomainError::main(source, input_index))
93 }
94
95 #[inline(always)]
97 pub const fn encode_domain_finish(source: EE) -> Self {
98 Self::EncodeDomain(TranscodeDomainError::finish(source))
99 }
100
101 #[inline(always)]
103 #[must_use]
104 pub fn unencodable(input_index: usize, value: V) -> Self {
105 Self::Unencodable {
106 input_index,
107 value: Some(value),
108 }
109 }
110
111 #[inline(always)]
113 #[must_use]
114 pub const fn unencodable_without_context(input_index: usize) -> Self {
115 Self::Unencodable {
116 input_index,
117 value: None,
118 }
119 }
120
121 #[inline(always)]
123 #[must_use]
124 pub const fn failure_ref(&self) -> Option<&TranscodeFailure> {
125 match self {
126 Self::Failure(failure) => Some(failure),
127 Self::DecodeDomain(_) | Self::EncodeDomain(_) | Self::Unencodable { .. } => None,
128 }
129 }
130
131 #[inline(always)]
133 #[must_use]
134 pub const fn unencodable_ref(&self) -> Option<(usize, Option<&V>)> {
135 match self {
136 Self::Unencodable { input_index, value } => Some((*input_index, value.as_ref())),
137 Self::Failure(_) | Self::DecodeDomain(_) | Self::EncodeDomain(_) => None,
138 }
139 }
140
141 #[inline]
143 pub fn map_decode_domain<F, T>(self, f: F) -> TranscodeConvertError<T, EE, V>
144 where
145 F: FnOnce(DE) -> T,
146 {
147 match self {
148 Self::Failure(failure) => TranscodeConvertError::Failure(failure),
149 Self::DecodeDomain(error) => TranscodeConvertError::DecodeDomain(error.map_source(f)),
150 Self::EncodeDomain(error) => TranscodeConvertError::EncodeDomain(error),
151 Self::Unencodable { input_index, value } => TranscodeConvertError::Unencodable { input_index, value },
152 }
153 }
154
155 #[inline]
157 pub fn map_encode_domain<F, T>(self, f: F) -> TranscodeConvertError<DE, T, V>
158 where
159 F: FnOnce(EE) -> T,
160 {
161 match self {
162 Self::Failure(failure) => TranscodeConvertError::Failure(failure),
163 Self::DecodeDomain(error) => TranscodeConvertError::DecodeDomain(error),
164 Self::EncodeDomain(error) => TranscodeConvertError::EncodeDomain(error.map_source(f)),
165 Self::Unencodable { input_index, value } => TranscodeConvertError::Unencodable { input_index, value },
166 }
167 }
168
169 #[inline]
171 pub fn map_value<F, W>(self, f: F) -> TranscodeConvertError<DE, EE, W>
172 where
173 F: FnOnce(V) -> W,
174 {
175 match self {
176 Self::Failure(failure) => TranscodeConvertError::Failure(failure),
177 Self::DecodeDomain(error) => TranscodeConvertError::DecodeDomain(error),
178 Self::EncodeDomain(error) => TranscodeConvertError::EncodeDomain(error),
179 Self::Unencodable { input_index, value } => TranscodeConvertError::Unencodable {
180 input_index,
181 value: value.map(f),
182 },
183 }
184 }
185
186 #[inline]
189 pub fn from_encode_error_with_value(error: TranscodeEncodeError<EE, V>, fallback_value: V) -> Self {
190 match error {
191 TranscodeEncodeError::Unencodable {
192 input_index,
193 value: None,
194 } => Self::Unencodable {
195 input_index,
196 value: Some(fallback_value),
197 },
198 other => Self::from(other),
199 }
200 }
201}
202
203impl<DE, EE, V> From<TranscodeDecodeError<DE>> for TranscodeConvertError<DE, EE, V> {
204 #[inline]
206 fn from(error: TranscodeDecodeError<DE>) -> Self {
207 match error {
208 TranscodeDecodeError::Failure(failure) => Self::Failure(failure),
209 TranscodeDecodeError::Domain(error) => Self::DecodeDomain(error),
210 }
211 }
212}
213
214impl<DE, EE, V> From<TranscodeEncodeError<EE, V>> for TranscodeConvertError<DE, EE, V> {
215 #[inline]
217 fn from(error: TranscodeEncodeError<EE, V>) -> Self {
218 match error {
219 TranscodeEncodeError::Failure(failure) => Self::Failure(failure),
220 TranscodeEncodeError::Unencodable { input_index, value } => Self::Unencodable { input_index, value },
221 TranscodeEncodeError::Domain(error) => Self::EncodeDomain(error),
222 }
223 }
224}
225
226impl<DE, EE, V> From<CapacityError> for TranscodeConvertError<DE, EE, V> {
227 #[inline(always)]
229 fn from(error: CapacityError) -> Self {
230 TranscodeFailure::from(error).into()
231 }
232}