Skip to content

Commit

Permalink
Merge pull request #22 from worm-blossom/separate_errors
Browse files Browse the repository at this point in the history
Define separate error types per module
  • Loading branch information
AljoschaMeyer authored Jun 20, 2024
2 parents 4e3d4a9 + 8aed214 commit 6c714dc
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 27 deletions.
15 changes: 11 additions & 4 deletions src/local_nb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use core::future::Future;
use core::mem::MaybeUninit;

use either::Either;

use crate::sync::{PipeError};
use thiserror::Error;

pub mod consumer;
pub mod producer;
Expand Down Expand Up @@ -273,6 +272,15 @@ where
}
}

/// Everything that can go wrong when piping a `Producer` into a `Consumer`.
#[derive(Clone, Copy, Debug, Error, Eq, PartialEq)]
pub enum PipeError<ProducerError, ConsumerError> {
/// The `Producer` emitted an error.
Producer(ProducerError),
/// The `Consumer` emitted an error when consuming an `Item`.
Consumer(ConsumerError),
}

/// Pipe as many items as possible from a producer into a consumer. Then call `close`
/// on the consumer with the final value emitted by the producer.
pub async fn pipe<P, C>(
Expand Down Expand Up @@ -353,9 +361,8 @@ where
mod tests {
use super::*;

use crate::local_nb::consumer::{IntoVec, SliceConsumer};
use crate::local_nb::consumer::{IntoVec, SliceConsumer, SliceConsumerFullError};
use crate::local_nb::producer::SliceProducer;
use crate::sync::consumer::SliceConsumerFullError;

#[test]
fn pipes_from_slice_producer_to_slice_consumer(
Expand Down
4 changes: 2 additions & 2 deletions src/local_nb/consumer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ mod scramble;
#[cfg(any(feature = "std", feature = "alloc"))]
pub use into_vec::IntoVec;
#[cfg(any(feature = "std", feature = "alloc"))]
pub use into_vec_fallible::IntoVecFallible;
pub use into_vec_fallible::{IntoVecError, IntoVecFallible};

pub use slice_consumer::SliceConsumer;
pub use slice_consumer::{SliceConsumer, SliceConsumerFullError};

pub use sync_to_local_nb::SyncToLocalNb;

Expand Down
35 changes: 26 additions & 9 deletions src/local_nb/consumer/into_vec_fallible.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,25 @@ use alloc::{
#[cfg(feature = "std")]
use std::{
alloc::{Allocator, Global},
collections::TryReserveError,
vec::Vec,
};

use thiserror::Error;
use wrapper::Wrapper;

use crate::local_nb::consumer::SyncToLocalNb;
use crate::local_nb::{BufferedConsumer, BulkConsumer, Consumer};
use crate::sync::consumer::{IntoVecError, IntoVecFallible as SyncIntoVecFallible};
use crate::sync::consumer::IntoVecFallible as SyncIntoVecFallible;

#[derive(Clone, Debug, Error, Eq, PartialEq)]
#[error(transparent)]
/// Error to indicate that consuming data into a `Vec` failed because allocating more memory for the `Vec` failed.
pub struct IntoVecError(#[from] pub TryReserveError);

/// Collects data and can at any point be converted into a `Vec<T>`. Unlike [`IntoVec`](crate::sync::consumer::IntoVec), reports an error instead of panicking when an internal memory allocation fails.
#[derive(Debug)]
pub struct IntoVecFallible<T, A: Allocator = Global>(
SyncToLocalNb<SyncIntoVecFallible<T, A>>,
);
pub struct IntoVecFallible<T, A: Allocator = Global>(SyncToLocalNb<SyncIntoVecFallible<T, A>>);

impl<T> Default for IntoVecFallible<T> {
fn default() -> Self {
Expand Down Expand Up @@ -77,17 +82,23 @@ impl<T> Consumer for IntoVecFallible<T> {
type Error = IntoVecError;

async fn consume(&mut self, item: Self::Item) -> Result<(), Self::Error> {
self.0.consume(item).await
self.0
.consume(item)
.await
.map_err(|err| IntoVecError(err.0))
}

async fn close(&mut self, final_val: Self::Final) -> Result<(), Self::Error> {
self.0.close(final_val).await
self.0
.close(final_val)
.await
.map_err(|err| IntoVecError(err.0))
}
}

impl<T> BufferedConsumer for IntoVecFallible<T> {
async fn flush(&mut self) -> Result<(), Self::Error> {
self.0.flush().await
self.0.flush().await.map_err(|err| IntoVecError(err.0))
}
}

Expand All @@ -98,11 +109,17 @@ impl<T: Copy> BulkConsumer for IntoVecFallible<T> {
where
T: 'a,
{
self.0.consumer_slots().await
self.0
.consumer_slots()
.await
.map_err(|err| IntoVecError(err.0))
}

async unsafe fn did_consume(&mut self, amount: usize) -> Result<(), Self::Error> {
self.0.did_consume(amount).await
self.0
.did_consume(amount)
.await
.map_err(|err| IntoVecError(err.0))
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/local_nb/consumer/invariant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,7 @@ where
mod tests {
use super::*;

use crate::local_nb::consumer::{IntoVec, SliceConsumer};
use crate::sync::consumer::SliceConsumerFullError;
use crate::local_nb::consumer::{IntoVec, SliceConsumer, SliceConsumerFullError};

#[test]
fn accepts_valid_did_consume_amount() {
Expand Down
31 changes: 24 additions & 7 deletions src/local_nb/consumer/slice_consumer.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
use core::convert::{AsMut, AsRef};
use core::mem::MaybeUninit;

use thiserror::Error;
use wrapper::Wrapper;

use crate::local_nb::consumer::SyncToLocalNb;
use crate::local_nb::{BufferedConsumer, BulkConsumer, Consumer};
use crate::sync::consumer::{SliceConsumer as SyncSliceConsumer, SliceConsumerFullError};
use crate::sync::consumer::SliceConsumer as SyncSliceConsumer;

#[derive(Clone, Copy, Debug, Error, Eq, PartialEq)]
#[error("slice consumer is full")]
/// Error to indicate that consuming data into a slice failed because the end of the slice was reached.
pub struct SliceConsumerFullError;

/// Consumes data into a mutable slice.
#[derive(Debug)]
pub struct SliceConsumer<'a, T>(SyncToLocalNb<SyncSliceConsumer<'a, T>>);

Expand Down Expand Up @@ -51,17 +56,23 @@ impl<'a, T> Consumer for SliceConsumer<'a, T> {
type Error = SliceConsumerFullError;

async fn consume(&mut self, item: Self::Item) -> Result<(), Self::Error> {
self.0.consume(item).await
self.0
.consume(item)
.await
.map_err(|_| SliceConsumerFullError)
}

async fn close(&mut self, final_val: Self::Final) -> Result<(), Self::Error> {
self.0.close(final_val).await
self.0
.close(final_val)
.await
.map_err(|_| SliceConsumerFullError)
}
}

impl<'a, T> BufferedConsumer for SliceConsumer<'a, T> {
async fn flush(&mut self) -> Result<(), Self::Error> {
self.0.flush().await
self.0.flush().await.map_err(|_| SliceConsumerFullError)
}
}

Expand All @@ -72,11 +83,17 @@ impl<'a, T: Copy> BulkConsumer for SliceConsumer<'a, T> {
where
T: 'b,
{
self.0.consumer_slots().await
self.0
.consumer_slots()
.await
.map_err(|_| SliceConsumerFullError)
}

async unsafe fn did_consume(&mut self, amount: usize) -> Result<(), Self::Error> {
self.0.did_consume(amount).await
self.0
.did_consume(amount)
.await
.map_err(|_| SliceConsumerFullError)
}
}

Expand Down
12 changes: 10 additions & 2 deletions src/nb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use core::future::Future;
use core::mem::MaybeUninit;

use either::Either;

use crate::sync::{PipeError};
use thiserror::Error;

/// A `Consumer` consumes a potentially infinite sequence, one item at a time.
///
Expand Down Expand Up @@ -274,6 +273,15 @@ where
}
}

/// Everything that can go wrong when piping a `Producer` into a `Consumer`.
#[derive(Clone, Copy, Debug, Error, Eq, PartialEq)]
pub enum PipeError<ProducerError, ConsumerError> {
/// The `Producer` emitted an error.
Producer(ProducerError),
/// The `Consumer` emitted an error when consuming an `Item`.
Consumer(ConsumerError),
}

/// Pipe as many items as possible from a producer into a consumer. Then call `close`
/// on the consumer with the final value emitted by the producer.
pub async fn pipe<P, C>(
Expand Down
2 changes: 1 addition & 1 deletion src/sync/consumer/into_vec_fallible.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::sync::{BufferedConsumer, BulkConsumer, Consumer};
#[derive(Clone, Debug, Error, Eq, PartialEq)]
#[error(transparent)]
/// Error to indicate that consuming data into a `Vec` failed because allocating more memory for the `Vec` failed.
pub struct IntoVecError(#[from] TryReserveError);
pub struct IntoVecError(#[from] pub TryReserveError);

/// Collects data and can at any point be converted into a `Vec<T>`. Unlike [`IntoVec`](crate::sync::consumer::IntoVec), reports an error instead of panicking when an internal memory allocation fails.
#[derive(Debug)]
Expand Down

0 comments on commit 6c714dc

Please sign in to comment.