use core::num::NonZeroUsize;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct InsufficientData {
required: Option<NonZeroUsize>,
available: usize,
}
impl InsufficientData {
#[inline]
pub const fn new(available: usize) -> Self {
Self {
required: None,
available,
}
}
#[inline]
pub const fn with_required(required: NonZeroUsize, available: usize) -> Self {
assert!(
required.get() > available,
"InsufficientData: required must be greater than available"
);
Self {
required: Some(required),
available,
}
}
#[inline]
pub const fn required(&self) -> Option<NonZeroUsize> {
self.required
}
#[inline]
pub const fn available(&self) -> usize {
self.available
}
}
impl core::fmt::Display for InsufficientData {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self.required {
Some(required) => write!(
f,
"not enough bytes to decode value (required {} but only {} available)",
required, self.available
),
None => write!(
f,
"not enough bytes to decode value (only {} available)",
self.available
),
}
}
}
impl core::error::Error for InsufficientData {}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl From<InsufficientData> for std::io::Error {
fn from(err: InsufficientData) -> Self {
std::io::Error::new(std::io::ErrorKind::UnexpectedEof, err)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, thiserror::Error)]
#[error(
"not enough space available to encode value (requested {requested} but only {available} available)"
)]
pub struct InsufficientSpace {
requested: NonZeroUsize,
available: usize,
}
impl InsufficientSpace {
#[inline]
pub const fn new(requested: NonZeroUsize, available: usize) -> Self {
assert!(
requested.get() > available,
"InsufficientSpace: requested must be greater than available"
);
Self {
requested,
available,
}
}
#[inline]
pub const fn requested(&self) -> NonZeroUsize {
self.requested
}
#[inline]
pub const fn available(&self) -> usize {
self.available
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl From<InsufficientSpace> for std::io::Error {
fn from(err: InsufficientSpace) -> Self {
std::io::Error::new(std::io::ErrorKind::WriteZero, err)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, thiserror::Error)]
#[non_exhaustive]
pub enum ConstEncodeError {
#[error(transparent)]
InsufficientSpace(#[from] InsufficientSpace),
#[error("{0}")]
Other(&'static str),
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl From<ConstEncodeError> for std::io::Error {
fn from(err: ConstEncodeError) -> Self {
match err {
ConstEncodeError::InsufficientSpace(err) => {
std::io::Error::new(std::io::ErrorKind::WriteZero, err)
}
ConstEncodeError::Other(msg) => std::io::Error::other(msg),
}
}
}
impl ConstEncodeError {
#[inline]
pub const fn insufficient_space(requested: NonZeroUsize, available: usize) -> Self {
Self::InsufficientSpace(InsufficientSpace::new(requested, available))
}
#[inline]
pub const fn other(msg: &'static str) -> Self {
Self::Other(msg)
}
#[inline]
pub(super) const fn update(self, requested: NonZeroUsize, available: usize) -> Self {
match self {
Self::InsufficientSpace(_) => {
Self::InsufficientSpace(InsufficientSpace::new(requested, available))
}
Self::Other(msg) => Self::Other(msg),
}
}
#[inline]
pub const fn into_encode_error(self) -> EncodeError {
match self {
Self::InsufficientSpace(iss) => EncodeError::InsufficientSpace(iss),
#[cfg(any(feature = "std", feature = "alloc"))]
Self::Other(msg) => EncodeError::Other(std::borrow::Cow::Borrowed(msg)),
#[cfg(not(any(feature = "std", feature = "alloc")))]
Self::Other(msg) => EncodeError::Other(msg),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, thiserror::Error)]
#[non_exhaustive]
pub enum ConstDecodeError {
#[error("decoded value would overflow the target type")]
Overflow,
#[error(transparent)]
InsufficientData(#[from] InsufficientData),
#[error("{0}")]
Other(&'static str),
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl From<ConstDecodeError> for std::io::Error {
fn from(err: ConstDecodeError) -> Self {
match err {
ConstDecodeError::Overflow => std::io::Error::new(std::io::ErrorKind::InvalidData, err),
ConstDecodeError::InsufficientData(err) => {
std::io::Error::new(std::io::ErrorKind::UnexpectedEof, err)
}
ConstDecodeError::Other(msg) => std::io::Error::other(msg),
}
}
}
impl ConstDecodeError {
#[inline]
pub const fn overflow() -> Self {
Self::Overflow
}
#[inline]
pub const fn insufficient_data(available: usize) -> Self {
Self::InsufficientData(InsufficientData::new(available))
}
#[inline]
pub const fn insufficient_data_with_required(required: NonZeroUsize, available: usize) -> Self {
Self::InsufficientData(InsufficientData::with_required(required, available))
}
#[inline]
pub const fn other(msg: &'static str) -> Self {
Self::Other(msg)
}
#[inline]
pub const fn into_decode_error(self) -> DecodeError {
match self {
Self::Overflow => DecodeError::Overflow,
Self::InsufficientData(e) => DecodeError::InsufficientData(e),
#[cfg(any(feature = "std", feature = "alloc"))]
Self::Other(msg) => DecodeError::Other(std::borrow::Cow::Borrowed(msg)),
#[cfg(not(any(feature = "std", feature = "alloc")))]
Self::Other(msg) => DecodeError::Other(msg),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, thiserror::Error)]
#[non_exhaustive]
pub enum EncodeError {
#[error(transparent)]
InsufficientSpace(#[from] InsufficientSpace),
#[cfg(not(any(feature = "std", feature = "alloc")))]
#[error("{0}")]
Other(&'static str),
#[error("{0}")]
#[cfg(any(feature = "std", feature = "alloc"))]
Other(std::borrow::Cow<'static, str>),
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl From<EncodeError> for std::io::Error {
fn from(err: EncodeError) -> Self {
match err {
EncodeError::InsufficientSpace(err) => {
std::io::Error::new(std::io::ErrorKind::WriteZero, err)
}
EncodeError::Other(msg) => std::io::Error::other(msg),
}
}
}
impl From<ConstEncodeError> for EncodeError {
fn from(err: ConstEncodeError) -> Self {
match err {
ConstEncodeError::InsufficientSpace(iss) => EncodeError::InsufficientSpace(iss),
ConstEncodeError::Other(msg) => EncodeError::other(msg),
}
}
}
impl EncodeError {
#[inline]
pub const fn insufficient_space(requested: NonZeroUsize, available: usize) -> Self {
Self::InsufficientSpace(InsufficientSpace::new(requested, available))
}
#[inline]
#[cfg(not(any(feature = "std", feature = "alloc")))]
pub const fn other(msg: &'static str) -> Self {
Self::Other(msg)
}
#[inline]
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn other(msg: impl Into<std::borrow::Cow<'static, str>>) -> Self {
Self::Other(msg.into())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, thiserror::Error)]
#[non_exhaustive]
pub enum DecodeError {
#[error("decoded value would overflow the target type")]
Overflow,
#[error(transparent)]
InsufficientData(#[from] InsufficientData),
#[error("{0}")]
#[cfg(not(any(feature = "std", feature = "alloc")))]
Other(&'static str),
#[error("{0}")]
#[cfg(any(feature = "std", feature = "alloc"))]
Other(std::borrow::Cow<'static, str>),
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl From<DecodeError> for std::io::Error {
fn from(err: DecodeError) -> Self {
match err {
DecodeError::Overflow => std::io::Error::new(std::io::ErrorKind::InvalidData, err),
DecodeError::InsufficientData(err) => {
std::io::Error::new(std::io::ErrorKind::UnexpectedEof, err)
}
DecodeError::Other(msg) => std::io::Error::other(msg),
}
}
}
impl From<ConstDecodeError> for DecodeError {
fn from(err: ConstDecodeError) -> Self {
match err {
ConstDecodeError::Overflow => Self::Overflow,
ConstDecodeError::InsufficientData(e) => Self::InsufficientData(e),
ConstDecodeError::Other(msg) => Self::other(msg),
}
}
}
impl DecodeError {
#[inline]
pub const fn overflow() -> Self {
Self::Overflow
}
#[inline]
pub const fn insufficient_data(available: usize) -> Self {
Self::InsufficientData(InsufficientData::new(available))
}
#[inline]
pub const fn insufficient_data_with_required(required: NonZeroUsize, available: usize) -> Self {
Self::InsufficientData(InsufficientData::with_required(required, available))
}
#[inline]
#[cfg(not(any(feature = "std", feature = "alloc")))]
pub const fn other(msg: &'static str) -> Self {
Self::Other(msg)
}
#[inline]
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn other(msg: impl Into<std::borrow::Cow<'static, str>>) -> Self {
Self::Other(msg.into())
}
}