use thiserror::Error;
use super::capacity_error::CapacityError;
use super::transcode_domain_error::TranscodeDomainError;
use super::transcode_failure::TranscodeFailure;
use crate::Codec;
pub type TranscodeEncodeErrorOf<C> = TranscodeEncodeError<<C as Codec>::EncodeError, <C as Codec>::Value>;
#[derive(Clone, Debug, Eq, Error, Hash, PartialEq)]
#[must_use]
pub enum TranscodeEncodeError<E, V> {
#[error(transparent)]
Failure(
#[from]
TranscodeFailure,
),
#[error("unencodable value at input index {input_index}")]
Unencodable {
input_index: usize,
value: Option<V>,
},
#[error(transparent)]
Domain(
#[from]
TranscodeDomainError<E>,
),
}
impl<E, V> TranscodeEncodeError<E, V> {
#[inline]
pub const fn domain_reset(source: E) -> Self {
Self::Domain(TranscodeDomainError::reset(source))
}
#[inline]
pub const fn domain_main(source: E, input_index: usize) -> Self {
Self::Domain(TranscodeDomainError::main(source, input_index))
}
#[inline]
pub const fn domain_finish(source: E) -> Self {
Self::Domain(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]
#[must_use]
pub const fn is_domain(&self) -> bool {
matches!(self, Self::Domain(_))
}
#[inline]
pub const fn failure_ref(&self) -> Option<&TranscodeFailure> {
match self {
Self::Failure(failure) => Some(failure),
Self::Unencodable { .. } | Self::Domain(_) => None,
}
}
#[inline]
pub const fn domain_error_ref(&self) -> Option<&TranscodeDomainError<E>> {
match self {
Self::Domain(error) => Some(error),
Self::Failure(_) | Self::Unencodable { .. } => None,
}
}
#[inline]
pub const fn domain_ref(&self) -> Option<&E> {
match self {
Self::Domain(error) => Some(error.source()),
Self::Failure(_) | 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::Domain(_) => None,
}
}
#[inline]
pub fn map_domain<F, T>(self, f: F) -> TranscodeEncodeError<T, V>
where
F: FnOnce(E) -> T,
{
match self {
Self::Failure(failure) => TranscodeEncodeError::Failure(failure),
Self::Unencodable { input_index, value } => TranscodeEncodeError::Unencodable { input_index, value },
Self::Domain(error) => TranscodeEncodeError::Domain(error.map_source(f)),
}
}
#[inline]
pub fn map_value<F, W>(self, f: F) -> TranscodeEncodeError<E, W>
where
F: FnOnce(V) -> W,
{
match self {
Self::Failure(failure) => TranscodeEncodeError::Failure(failure),
Self::Unencodable { input_index, value } => TranscodeEncodeError::Unencodable {
input_index,
value: value.map(f),
},
Self::Domain(error) => TranscodeEncodeError::Domain(error),
}
}
}
impl<E, V> From<CapacityError> for TranscodeEncodeError<E, V> {
#[inline]
fn from(error: CapacityError) -> Self {
TranscodeFailure::from(error).into()
}
}