use thiserror::Error;
use super::config::SizeOverflow;
use super::core::CoreError;
use super::core::stream::StreamError;
use crate::graph::GraphError;
#[derive(Error, Debug, Clone, Eq, PartialEq)]
#[non_exhaustive]
pub enum EncodeError {
#[error("a destination of {provided} bytes cannot hold the compressed frame")]
OutputTooSmall {
provided: usize,
},
#[error("the stream was declared as {declared} bytes but received a different amount")]
InputSizeMismatch {
declared: u64,
},
#[error("the session cannot accept this operation in its current state")]
InvalidState,
#[error(transparent)]
Bound(#[from] SizeOverflow),
#[error(transparent)]
Graph(#[from] GraphError),
#[error("internal encoder failure")]
Internal,
}
impl EncodeError {
pub(crate) fn from_core(error: CoreError, provided: usize) -> Self {
match error {
CoreError::Graph(error) => Self::Graph(GraphError::from(error)),
CoreError::OutputFull => Self::OutputTooSmall { provided },
#[cfg(feature = "zstd")]
CoreError::Internal => Self::Internal,
}
}
pub(crate) const fn from_stream(error: StreamError, declared: Option<u64>) -> Self {
match error {
StreamError::SizeMismatch => Self::InputSizeMismatch {
declared: match declared {
Some(size) => size,
None => 0,
},
},
StreamError::Core(_) => Self::Internal,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::string::ToString;
#[test]
fn core_errors_map_to_public_variants() {
assert_eq!(
EncodeError::from_core(CoreError::OutputFull, 3),
EncodeError::OutputTooSmall { provided: 3 }
);
#[cfg(feature = "zstd")]
assert_eq!(
EncodeError::from_core(CoreError::Internal, 0),
EncodeError::Internal
);
assert_eq!(
EncodeError::from_stream(StreamError::SizeMismatch, Some(9)),
EncodeError::InputSizeMismatch { declared: 9 }
);
assert_eq!(
EncodeError::from_stream(StreamError::SizeMismatch, None),
EncodeError::InputSizeMismatch { declared: 0 }
);
assert_eq!(
EncodeError::from_stream(StreamError::Core(CoreError::OutputFull), None),
EncodeError::Internal
);
assert_eq!(
EncodeError::from(SizeOverflow),
EncodeError::Bound(SizeOverflow)
);
}
#[test]
fn messages_describe_the_failure() {
assert!(
EncodeError::OutputTooSmall { provided: 4 }
.to_string()
.contains('4')
);
assert!(EncodeError::InvalidState.to_string().contains("state"));
assert!(EncodeError::Internal.to_string().contains("internal"));
}
}