use std::{convert::Infallible, error::Error};
use crate::{
fail::{Fail, Rejection},
profile::LaneProfile,
};
pub trait RejectedSlot: Send + Sync + 'static {}
impl RejectedSlot for Infallible {}
impl<R: Rejection> RejectedSlot for R {}
#[doc(hidden)]
pub trait RejectedUnion<Other: RejectedSlot>: RejectedSlot {
type Out: RejectedSlot;
}
impl RejectedUnion<Infallible> for Infallible {
type Out = Infallible;
}
impl<R: Rejection> RejectedUnion<Infallible> for R {
type Out = R;
}
impl<R: Rejection> RejectedUnion<R> for Infallible {
type Out = R;
}
impl<R: Rejection> RejectedUnion<R> for R {
type Out = R;
}
#[diagnostic::on_unimplemented(
message = "`{Self}` does not say how it enters the lanes",
note = "derive `errlanes::Rejection` if a caller can correct it, or `errlanes::Classify` \
with a lane (`#[classify(fatal(Kind))]`, …); a foreign error is wrapped in a \
local type first"
)]
pub trait Classify: Error + Send + Sync + 'static {
type Rejected: RejectedSlot;
type Lanes: LaneProfile;
fn classify(self) -> Fail<Self::Rejected, Self::Lanes>;
}
impl<R: Rejection> Classify for R {
type Rejected = R;
type Lanes = crate::profile::NoLanes;
fn classify(self) -> Fail<R, Self::Lanes> {
Fail::Rejected(self)
}
}