use thiserror::Error;
use super::capacity_error::CapacityError;
use super::transcode_decode_errors::TranscodeDecodeError;
use super::transcode_domain_error::TranscodeDomainError;
use super::transcode_encode_error::TranscodeEncodeError;
use super::transcode_failure::TranscodeFailure;
use crate::Codec;
pub type TranscodeConvertErrorOf<D, E> =
TranscodeConvertError<<D as Codec>::DecodeError, <E as Codec>::EncodeError, <D as Codec>::Value>;
#[derive(Clone, Debug, Eq, Error, Hash, PartialEq)]
#[must_use]
pub enum TranscodeConvertError<DE, EE, V> {
#[error(transparent)]
Failure(
#[from]
TranscodeFailure,
),
#[error("decode side failed: {0}")]
DecodeDomain(
#[source]
TranscodeDomainError<DE>,
),
#[error("encode side failed: {0}")]
EncodeDomain(
#[source]
TranscodeDomainError<EE>,
),
#[error("unencodable value at input index {input_index}")]
Unencodable {
input_index: usize,
value: Option<V>,
},
}
impl<DE, EE, V> TranscodeConvertError<DE, EE, V> {
#[inline]
pub const fn decode_domain_reset(source: DE) -> Self {
Self::DecodeDomain(TranscodeDomainError::reset(source))
}
#[inline]
pub const fn decode_domain_main(source: DE, input_index: usize) -> Self {
Self::DecodeDomain(TranscodeDomainError::main(source, input_index))
}
#[inline]
pub const fn decode_domain_main_with_consumed(
source: DE,
input_index: usize,
input_consumed: Option<core::num::NonZeroUsize>,
) -> Self {
Self::DecodeDomain(TranscodeDomainError::main_with_consumed(
source,
input_index,
input_consumed,
))
}
#[inline]
pub const fn decode_domain_finish(source: DE) -> Self {
Self::DecodeDomain(TranscodeDomainError::finish(source))
}
#[inline]
pub const fn encode_domain_reset(source: EE) -> Self {
Self::EncodeDomain(TranscodeDomainError::reset(source))
}
#[inline]
pub const fn encode_domain_main(source: EE, input_index: usize) -> Self {
Self::EncodeDomain(TranscodeDomainError::main(source, input_index))
}
#[inline]
pub const fn encode_domain_finish(source: EE) -> Self {
Self::EncodeDomain(TranscodeDomainError::finish(source))
}
#[inline]
pub fn unencodable(input_index: usize, value: V) -> Self {
Self::Unencodable {
input_index,
value: Some(value),
}
}
#[inline]
pub const fn unencodable_without_context(input_index: usize) -> Self {
Self::Unencodable {
input_index,
value: None,
}
}
#[inline]
pub fn from_encode_error_with_value(error: TranscodeEncodeError<EE, V>, fallback_value: V) -> Self {
match error {
TranscodeEncodeError::Unencodable {
input_index,
value: None,
} => Self::Unencodable {
input_index,
value: Some(fallback_value),
},
other => Self::from(other),
}
}
#[inline]
pub const fn failure_ref(&self) -> Option<&TranscodeFailure> {
match self {
Self::Failure(failure) => Some(failure),
Self::DecodeDomain(_) | Self::EncodeDomain(_) | Self::Unencodable { .. } => None,
}
}
#[inline]
pub const fn unencodable_ref(&self) -> Option<(usize, Option<&V>)> {
match self {
Self::Unencodable { input_index, value } => Some((*input_index, value.as_ref())),
Self::Failure(_) | Self::DecodeDomain(_) | Self::EncodeDomain(_) => None,
}
}
#[inline]
pub fn map_decode_domain<F, T>(self, f: F) -> TranscodeConvertError<T, EE, V>
where
F: FnOnce(DE) -> T,
{
match self {
Self::Failure(failure) => TranscodeConvertError::Failure(failure),
Self::DecodeDomain(error) => TranscodeConvertError::DecodeDomain(error.map_source(f)),
Self::EncodeDomain(error) => TranscodeConvertError::EncodeDomain(error),
Self::Unencodable { input_index, value } => TranscodeConvertError::Unencodable { input_index, value },
}
}
#[inline]
pub fn map_encode_domain<F, T>(self, f: F) -> TranscodeConvertError<DE, T, V>
where
F: FnOnce(EE) -> T,
{
match self {
Self::Failure(failure) => TranscodeConvertError::Failure(failure),
Self::DecodeDomain(error) => TranscodeConvertError::DecodeDomain(error),
Self::EncodeDomain(error) => TranscodeConvertError::EncodeDomain(error.map_source(f)),
Self::Unencodable { input_index, value } => TranscodeConvertError::Unencodable { input_index, value },
}
}
#[inline]
pub fn map_value<F, W>(self, f: F) -> TranscodeConvertError<DE, EE, W>
where
F: FnOnce(V) -> W,
{
match self {
Self::Failure(failure) => TranscodeConvertError::Failure(failure),
Self::DecodeDomain(error) => TranscodeConvertError::DecodeDomain(error),
Self::EncodeDomain(error) => TranscodeConvertError::EncodeDomain(error),
Self::Unencodable { input_index, value } => TranscodeConvertError::Unencodable {
input_index,
value: value.map(f),
},
}
}
}
impl<DE, EE, V> From<TranscodeDecodeError<DE>> for TranscodeConvertError<DE, EE, V> {
#[inline]
fn from(error: TranscodeDecodeError<DE>) -> Self {
match error {
TranscodeDecodeError::Failure(failure) => Self::Failure(failure),
TranscodeDecodeError::Domain(error) => Self::DecodeDomain(error),
}
}
}
impl<DE, EE, V> From<TranscodeEncodeError<EE, V>> for TranscodeConvertError<DE, EE, V> {
#[inline]
fn from(error: TranscodeEncodeError<EE, V>) -> Self {
match error {
TranscodeEncodeError::Failure(failure) => Self::Failure(failure),
TranscodeEncodeError::Unencodable { input_index, value } => Self::Unencodable { input_index, value },
TranscodeEncodeError::Domain(error) => Self::EncodeDomain(error),
}
}
}
impl<DE, EE, V> From<CapacityError> for TranscodeConvertError<DE, EE, V> {
#[inline]
fn from(error: CapacityError) -> Self {
TranscodeFailure::from(error).into()
}
}