use crate::{
Report, ReportConversion, handlers,
markers::{Local, Mutable, SendSync},
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct NoneError {
type_name: &'static str,
}
impl NoneError {
#[must_use]
pub fn new<T: ?Sized>() -> Self {
Self {
type_name: core::any::type_name::<T>(),
}
}
#[must_use]
#[track_caller]
fn new_sendsync_report<T: ?Sized>() -> Report<NoneError, Mutable, SendSync> {
Report::new(Self::new::<T>())
}
#[must_use]
#[track_caller]
fn new_local_report<T: ?Sized>() -> Report<NoneError, Mutable, Local> {
Report::new_local(Self::new::<T>())
}
}
impl core::fmt::Display for NoneError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"Expected value of type {}, but found None",
self.type_name
)
}
}
impl core::error::Error for NoneError {}
pub trait OptionExt<V> {
#[track_caller]
fn ok_or_report(self) -> Result<V, Report<NoneError, Mutable, SendSync>>;
#[track_caller]
fn context<C>(self, context: C) -> Result<V, Report<C, Mutable, SendSync>>
where
C: Send + Sync + core::fmt::Display + core::fmt::Debug;
#[track_caller]
fn context_with<C, F>(self, context: F) -> Result<V, Report<C, Mutable, SendSync>>
where
F: FnOnce() -> C,
C: Send + Sync + core::fmt::Display + core::fmt::Debug;
#[track_caller]
fn context_custom<H, C>(self, context: C) -> Result<V, Report<C, Mutable, SendSync>>
where
C: Send + Sync,
H: handlers::ContextHandler<C>;
#[track_caller]
fn context_custom_with<H, C, F>(self, context: F) -> Result<V, Report<C, Mutable, SendSync>>
where
F: FnOnce() -> C,
C: Send + Sync,
H: handlers::ContextHandler<C>;
#[track_caller]
fn context_to<C>(self) -> Result<V, Report<C, Mutable, SendSync>>
where
C: ReportConversion<NoneError, Mutable, SendSync>;
#[track_caller]
fn local_context<C>(self, context: C) -> Result<V, Report<C, Mutable, Local>>
where
C: core::fmt::Display + core::fmt::Debug;
#[track_caller]
fn local_context_with<C, F>(self, context: F) -> Result<V, Report<C, Mutable, Local>>
where
F: FnOnce() -> C,
C: core::fmt::Display + core::fmt::Debug;
#[track_caller]
fn local_context_custom<H, C>(self, context: C) -> Result<V, Report<C, Mutable, Local>>
where
C: 'static,
H: handlers::ContextHandler<C>;
#[track_caller]
fn local_context_custom_with<H, C, F>(self, context: F) -> Result<V, Report<C, Mutable, Local>>
where
F: FnOnce() -> C,
C: 'static,
H: handlers::ContextHandler<C>;
#[track_caller]
fn local_context_to<C>(self) -> Result<V, Report<C, Mutable, Local>>
where
C: ReportConversion<NoneError, Mutable, Local>;
}
impl<V> OptionExt<V> for Option<V> {
#[inline]
fn ok_or_report(self) -> Result<V, Report<NoneError, Mutable, SendSync>> {
match self {
Some(v) => Ok(v),
None => Err(NoneError::new_sendsync_report::<V>()),
}
}
#[inline]
fn context<C>(self, context: C) -> Result<V, Report<C, Mutable, SendSync>>
where
C: Send + Sync + core::fmt::Display + core::fmt::Debug,
{
match self {
Some(v) => Ok(v),
None => Err(NoneError::new_sendsync_report::<V>().context(context)),
}
}
#[inline]
fn context_with<C, F>(self, context: F) -> Result<V, Report<C, Mutable, SendSync>>
where
F: FnOnce() -> C,
C: Send + Sync + core::fmt::Display + core::fmt::Debug,
{
match self {
Some(v) => Ok(v),
None => Err(NoneError::new_sendsync_report::<V>().context(context())),
}
}
#[inline]
fn context_custom<H, C>(self, context: C) -> Result<V, Report<C, Mutable, SendSync>>
where
C: Send + Sync,
H: handlers::ContextHandler<C>,
{
match self {
Some(v) => Ok(v),
None => Err(NoneError::new_sendsync_report::<V>().context_custom::<H, _>(context)),
}
}
#[inline]
fn context_custom_with<H, C, F>(self, context: F) -> Result<V, Report<C, Mutable, SendSync>>
where
F: FnOnce() -> C,
C: Send + Sync,
H: handlers::ContextHandler<C>,
{
match self {
Some(v) => Ok(v),
None => Err(NoneError::new_sendsync_report::<V>().context_custom::<H, _>(context())),
}
}
#[inline]
fn context_to<C>(self) -> Result<V, Report<C, Mutable, SendSync>>
where
C: ReportConversion<NoneError, Mutable, SendSync>,
{
match self {
Some(v) => Ok(v),
None => Err(NoneError::new_sendsync_report::<V>().context_to()),
}
}
#[inline]
fn local_context<C>(self, context: C) -> Result<V, Report<C, Mutable, Local>>
where
C: core::fmt::Display + core::fmt::Debug,
{
match self {
Some(v) => Ok(v),
None => Err(NoneError::new_local_report::<V>().context(context)),
}
}
#[inline]
fn local_context_with<C, F>(self, context: F) -> Result<V, Report<C, Mutable, Local>>
where
F: FnOnce() -> C,
C: core::fmt::Display + core::fmt::Debug,
{
match self {
Some(v) => Ok(v),
None => Err(NoneError::new_local_report::<V>().context(context())),
}
}
#[inline]
fn local_context_custom<H, C>(self, context: C) -> Result<V, Report<C, Mutable, Local>>
where
C: 'static,
H: handlers::ContextHandler<C>,
{
match self {
Some(v) => Ok(v),
None => Err(NoneError::new_local_report::<V>().context_custom::<H, _>(context)),
}
}
#[inline]
fn local_context_custom_with<H, C, F>(self, context: F) -> Result<V, Report<C, Mutable, Local>>
where
F: FnOnce() -> C,
C: 'static,
H: handlers::ContextHandler<C>,
{
match self {
Some(v) => Ok(v),
None => Err(NoneError::new_local_report::<V>().context_custom::<H, _>(context())),
}
}
#[inline]
fn local_context_to<C>(self) -> Result<V, Report<C, Mutable, Local>>
where
C: ReportConversion<NoneError, Mutable, Local>,
{
match self {
Some(v) => Ok(v),
None => Err(NoneError::new_local_report::<V>().context_to()),
}
}
}