use thiserror::Error;
#[derive(Clone, Copy, Debug, Eq, Error, Hash, PartialEq)]
pub enum CodecEncodeError<E> {
#[error("codec encode error at input index {input_index}: {source}")]
Encode {
#[source]
source: E,
input_index: usize,
},
#[error("unencodable value at input index {input_index}")]
UnencodableValue {
input_index: usize,
},
#[error("invalid input index {index} for input length {len}")]
InvalidInputIndex {
index: usize,
len: usize,
},
#[error("invalid output index {index} for output length {len}")]
InvalidOutputIndex {
index: usize,
len: usize,
},
#[error(
"insufficient output at index {output_index}: required {required} units, available {available}"
)]
InsufficientOutput {
output_index: usize,
required: usize,
available: usize,
},
#[error("output length arithmetic overflow")]
OutputLengthOverflow,
}
impl<E> CodecEncodeError<E> {
#[must_use]
#[inline(always)]
pub const fn encode(source: E, input_index: usize) -> Self {
Self::Encode {
source,
input_index,
}
}
#[must_use]
#[inline(always)]
pub const fn unencodable_value(input_index: usize) -> Self {
Self::UnencodableValue { input_index }
}
#[must_use]
#[inline(always)]
pub const fn invalid_input_index(index: usize, len: usize) -> Self {
Self::InvalidInputIndex { index, len }
}
#[must_use]
#[inline(always)]
pub const fn invalid_output_index(index: usize, len: usize) -> Self {
Self::InvalidOutputIndex { index, len }
}
#[must_use]
#[inline(always)]
pub const fn insufficient_output(
output_index: usize,
required: usize,
available: usize,
) -> Self {
Self::InsufficientOutput {
output_index,
required,
available,
}
}
#[must_use]
#[inline(always)]
pub const fn output_length_overflow() -> Self {
Self::OutputLengthOverflow
}
#[inline]
pub fn ensure_input_index(
input_len: usize,
input_index: usize,
) -> Result<(), Self> {
if input_index > input_len {
return Err(Self::invalid_input_index(input_index, input_len));
}
Ok(())
}
#[inline]
pub fn ensure_output_index(
output_len: usize,
output_index: usize,
) -> Result<(), Self> {
if output_index > output_len {
return Err(Self::invalid_output_index(output_index, output_len));
}
Ok(())
}
#[inline]
pub fn ensure_output_capacity(
output_len: usize,
output_index: usize,
required: usize,
) -> Result<(), Self> {
Self::ensure_output_index(output_len, output_index)?;
let available = output_len - output_index;
if available < required {
return Err(Self::insufficient_output(
output_index,
required,
available,
));
}
Ok(())
}
}