Skip to content

Commit

Permalink
Add DelegateErrorRaiser
Browse files Browse the repository at this point in the history
  • Loading branch information
soareschen committed Jul 2, 2024
1 parent f66e644 commit edbae0a
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 42 deletions.
2 changes: 1 addition & 1 deletion crates/cgp-error-eyre/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use core::fmt::{Debug, Display};
use std::error::Error as StdError;

use cgp_core::prelude::*;
use cgp_core::error::{ErrorRaiser, ProvideErrorType};
use cgp_core::prelude::*;
use eyre::{eyre, Report};

pub struct ProvideEyreError;
Expand Down
2 changes: 1 addition & 1 deletion crates/cgp-error-std/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::error::Error as StdError;

use cgp_core::prelude::*;
use cgp_core::error::{ErrorRaiser, ProvideErrorType};
use cgp_core::prelude::*;

pub type Error = Box<dyn StdError + Send + Sync + 'static>;

Expand Down
17 changes: 17 additions & 0 deletions crates/cgp-error/src/can_raise_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use cgp_async::Async;
use cgp_component::{derive_component, DelegateComponent, HasComponents};

use crate::has_error_type::HasErrorType;

/**
Used for injecting external error types into [`Self::Error`](HasErrorType::Error).
As an example, if `Context: CanRaiseError<ParseIntError>`, then we would be
able to call `Context::raise_error(err)` for an error value
[`err: ParseIntError`](core::num::ParseIntError) and get back
a [`Context::Error`](HasErrorType::Error) value.
*/
#[derive_component(ErrorRaiserComponent, ErrorRaiser<Context>)]
pub trait CanRaiseError<E>: HasErrorType {
fn raise_error(e: E) -> Self::Error;
}
19 changes: 19 additions & 0 deletions crates/cgp-error/src/delegate_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use core::marker::PhantomData;

use cgp_component::DelegateComponent;

use crate::{ErrorRaiser, HasErrorType};

pub struct DelegateErrorRaiser<Components>(pub PhantomData<Components>);

impl<Context, Error, Components, Delegate> ErrorRaiser<Context, Error>
for DelegateErrorRaiser<Components>
where
Context: HasErrorType,
Components: DelegateComponent<Error, Delegate = Delegate>,
Delegate: ErrorRaiser<Context, Error>,
{
fn raise_error(e: Error) -> Context::Error {
Delegate::raise_error(e)
}
}
28 changes: 28 additions & 0 deletions crates/cgp-error/src/has_error_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use core::fmt::Debug;

use cgp_async::Async;
use cgp_component::{derive_component, DelegateComponent, HasComponents};

/**
This is used for contexts to declare that they have a _unique_ `Self::Error` type.
Although it is possible for each context to declare their own associated
`Error` type, doing so may result in having multiple ambiguous `Self::Error` types,
if there are multiple associated types with the same name in different traits.
As a result, it is better for context traits to include `HasError` as their
parent traits, so that multiple traits can all refer to the same abstract
`Self::Error` type.
*/
#[derive_component(ErrorTypeComponent, ProvideErrorType<Context>)]
pub trait HasErrorType: Async {
/**
The `Error` associated type is also required to implement [`Debug`].
This is to allow `Self::Error` to be used in calls like `.unwrap()`,
as well as for simpler error logging.
*/
type Error: Async + Debug;
}

pub type ErrorOf<Context> = <Context as HasErrorType>::Error;
46 changes: 6 additions & 40 deletions crates/cgp-error/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,7 @@
use core::fmt::Debug;
mod can_raise_error;
mod delegate_error;
mod has_error_type;

use cgp_async::Async;
use cgp_component::{derive_component, DelegateComponent, HasComponents};

/**
This is used for contexts to declare that they have a _unique_ `Self::Error` type.
Although it is possible for each context to declare their own associated
`Error` type, doing so may result in having multiple ambiguous `Self::Error` types,
if there are multiple associated types with the same name in different traits.
As a result, it is better for context traits to include `HasError` as their
parent traits, so that multiple traits can all refer to the same abstract
`Self::Error` type.
*/
#[derive_component(ErrorTypeComponent, ProvideErrorType<Context>)]
pub trait HasErrorType: Async {
/**
The `Error` associated type is also required to implement [`Debug`].
This is to allow `Self::Error` to be used in calls like `.unwrap()`,
as well as for simpler error logging.
*/
type Error: Async + Debug;
}

pub type ErrorOf<Context> = <Context as HasErrorType>::Error;

/**
Used for injecting external error types into [`Self::Error`](HasErrorType::Error).
As an example, if `Context: CanRaiseError<ParseIntError>`, then we would be
able to call `Context::raise_error(err)` for an error value
[`err: ParseIntError`](core::num::ParseIntError) and get back
a [`Context::Error`](HasErrorType::Error) value.
*/
#[derive_component(ErrorRaiserComponent, ErrorRaiser<Context>)]
pub trait CanRaiseError<E>: HasErrorType {
fn raise_error(e: E) -> Self::Error;
}
pub use can_raise_error::*;
pub use delegate_error::*;
pub use has_error_type::*;

0 comments on commit edbae0a

Please sign in to comment.