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>
where
Option<T>: IntoResultHow,
{
type Output = Result<<Self as IntoResultHow>::T, How>;
impl<T> Explain for Option<T> {
type Output = Result<T, How>;
#[inline(always)]
#[track_caller]
fn context(self, context: impl IntoContext) -> Self::Output {
// TODO: maybe add a toggle for the extra "Option::None" context
//Err(How::new(context))
self.into_result_how().map_err(#[inline(never)] move |e| e.context(context))
}
// TODO: maybe add a feature for the extra "Option::None" context
match self {
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
}
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 {
let mut b = f.debug_struct(std::any::type_name::<Self>());
let b = b

View File

@ -27,7 +27,10 @@ where
fn into<E: std::error::Error>(e: E) -> How {
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 {
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")]
#![forbid(unsafe_code)]
#![deny(unsafe_code)]
#![feature(backtrace)]
mod sealed;