Tweak context, add some accessors for context, use match instead of map_err/ok_or_else

This commit is contained in:
Michael Pfaff 2023-02-06 09:09:01 -05:00
parent c373ad327e
commit 710eb48e0c
4 changed files with 58 additions and 12 deletions

View File

@ -25,17 +25,17 @@ where
} }
} }
impl<T> Explain for Option<T> impl<T> Explain for Option<T> {
where type Output = Result<T, How>;
Option<T>: IntoResultHow,
{
type Output = Result<<Self as IntoResultHow>::T, How>;
#[inline(always)] #[inline(always)]
#[track_caller] #[track_caller]
fn context(self, context: impl IntoContext) -> Self::Output { fn context(self, context: impl IntoContext) -> Self::Output {
// TODO: maybe add a toggle for the extra "Option::None" context // TODO: maybe add a feature for the extra "Option::None" context
//Err(How::new(context)) match self {
self.into_result_how().map_err(#[inline(never)] move |e| e.context(context)) Some(t) => Ok(t),
} None => Err(How::new(context))
}
//self.into_result_how().map_err(#[inline(never)] move |e| e.context(context))
} }
}

View File

@ -56,6 +56,46 @@ impl How {
self.0.classified self.0.classified
} }
pub fn location(&self) -> &Context {
// SAFETY: we only ever push values into context, and the constructor ensures that there
// are at least 2 values in context.
let o = self.0.context.get(0);
if cfg!(debug_assertions) {
o.unwrap()
} else {
#[allow(unsafe_code)]
unsafe { o.unwrap_unchecked() }
}
}
pub fn top(&self) -> &Context {
// SAFETY: we only ever push values into context, and the constructor ensures that there
// are at least 2 values in context.
let o = self.0.context.get(1);
if cfg!(debug_assertions) {
o.unwrap()
} else {
#[allow(unsafe_code)]
unsafe { o.unwrap_unchecked() }
}
}
pub fn bottom(&self) -> &Context {
// SAFETY: we only ever push values into context, and the constructor ensures that there
// are at least 2 values in context.
let o = self.0.context.iter().next_back();
if cfg!(debug_assertions) {
o.unwrap()
} else {
#[allow(unsafe_code)]
unsafe { o.unwrap_unchecked() }
}
}
pub fn into_context(self) -> impl Iterator<Item = Context> {
self.0.context.into_iter()
}
fn fmt_debug_alternate(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt_debug_alternate(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let mut b = f.debug_struct(std::any::type_name::<Self>()); let mut b = f.debug_struct(std::any::type_name::<Self>());
let b = b let b = b

View File

@ -27,7 +27,10 @@ where
fn into<E: std::error::Error>(e: E) -> How { fn into<E: std::error::Error>(e: E) -> How {
How::new(e.to_string()) How::new(e.to_string())
} }
self.map_err(into) match self {
Ok(t) => Ok(t),
Err(e) => Err(into(e))
}
} }
} }
@ -51,6 +54,9 @@ impl<T> IntoResultHow for Option<T> {
fn into() -> How { fn into() -> How {
How::new("Option::None") How::new("Option::None")
} }
self.ok_or_else(into) match self {
Some(t) => Ok(t),
None => Err(into())
}
} }
} }

View File

@ -1,5 +1,5 @@
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
#![forbid(unsafe_code)] #![deny(unsafe_code)]
#![feature(backtrace)] #![feature(backtrace)]
mod sealed; mod sealed;