From 7fad5c186fd76904a8a58a9956aecce6d6040e2b Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Sun, 14 Jul 2024 11:44:24 +0100 Subject: [PATCH] Implement Error on EncodingConsumerError, DecodeError --- data-model/src/encoding/compact_width.rs | 7 ++- data-model/src/encoding/error.rs | 67 ++++++++++++++++++------ data-model/src/lib.rs | 2 +- 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/data-model/src/encoding/compact_width.rs b/data-model/src/encoding/compact_width.rs index de7e0f2..b768cc3 100644 --- a/data-model/src/encoding/compact_width.rs +++ b/data-model/src/encoding/compact_width.rs @@ -1,3 +1,5 @@ +use core::error::Error; + use crate::encoding::error::{DecodeError, EncodingConsumerError}; use crate::encoding::parameters::Decoder; use crate::encoding::unsigned_int::{U16BE, U32BE, U64BE, U8BE}; @@ -92,7 +94,10 @@ impl CompactWidth { pub async fn encode_compact_width_be>( value: u64, consumer: &mut Consumer, -) -> Result<(), EncodingConsumerError> { +) -> Result<(), EncodingConsumerError> +where + Consumer::Error: Error, +{ let width = CompactWidth::from_u64(value).width(); consumer diff --git a/data-model/src/encoding/error.rs b/data-model/src/encoding/error.rs index e1b3b3c..e3a0a56 100644 --- a/data-model/src/encoding/error.rs +++ b/data-model/src/encoding/error.rs @@ -1,9 +1,7 @@ +use core::error::Error; +use core::{fmt::Display, fmt::Formatter, num::TryFromIntError}; use either::Either; -use std::num::TryFromIntError; -use ufotofu::{ - common::errors::{ConsumeFullSliceError, OverwriteFullSliceError}, - local_nb::producer::PipeIntoSliceError, -}; +use ufotofu::common::errors::{ConsumeFullSliceError, OverwriteFullSliceError}; /// Returned when a encoding fails to be consumed by a [`ufotofu::local_nb::Consumer`]. #[derive(Debug, Clone, PartialEq, Eq)] @@ -23,6 +21,25 @@ impl From> for EncodingConsumerError { } } +impl Error for EncodingConsumerError +where + E: 'static + Error, +{ + fn source(&self) -> Option<&(dyn Error + 'static)> { + Some(&self.reason) + } +} + +impl Display for EncodingConsumerError { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + write!( + f, + "The consumer failed to consume after consuming {} bytes", + self.bytes_consumed + ) + } +} + /// Everything that can go wrong when decoding a value. #[derive(Debug, Clone, PartialEq, Eq)] pub enum DecodeError { @@ -34,8 +51,8 @@ pub enum DecodeError { U64DoesNotFitUsize, } -impl<'a, T, F, E> From> for DecodeError { - fn from(value: PipeIntoSliceError<'a, T, F, E>) -> Self { +impl From> for DecodeError { + fn from(value: OverwriteFullSliceError) -> Self { match value.reason { Either::Left(_) => DecodeError::InvalidInput, Either::Right(err) => DecodeError::Producer(err), @@ -43,17 +60,37 @@ impl<'a, T, F, E> From> for DecodeError { } } -impl<'a, T, F, E> From> for DecodeError { - fn from(value: OverwriteFullSliceError<'a, T, F, E>) -> Self { - match value.reason { - Either::Left(_) => DecodeError::InvalidInput, - Either::Right(err) => DecodeError::Producer(err), +impl From for DecodeError { + fn from(_: TryFromIntError) -> Self { + DecodeError::U64DoesNotFitUsize + } +} + +impl Error for DecodeError +where + E: 'static + Error, +{ + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + DecodeError::Producer(err) => Some(err), + DecodeError::InvalidInput => None, + DecodeError::U64DoesNotFitUsize => None, } } } -impl From for DecodeError { - fn from(_: TryFromIntError) -> Self { - DecodeError::U64DoesNotFitUsize +impl Display for DecodeError { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + match self { + DecodeError::Producer(_) => { + write!(f, "The underlying producer encountered an error",) + } + DecodeError::InvalidInput => { + write!(f, "Decoding failed due to receiving invalid input",) + } + DecodeError::U64DoesNotFitUsize => { + write!(f, "Tried (and failed) to decode a u64 to a 32-bit usize",) + } + } } } diff --git a/data-model/src/lib.rs b/data-model/src/lib.rs index 4b3f7b9..40524d6 100644 --- a/data-model/src/lib.rs +++ b/data-model/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(new_uninit, async_fn_traits)] +#![feature(new_uninit, async_fn_traits, error_in_core)] pub mod encoding; pub mod entry;