Refactoring, improve output
This commit is contained in:
parent
41e071bccf
commit
bbc7df28d8
|
@ -1,19 +1,40 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
/// Provides context furthering the explanation of *how* you got to an error.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Context(ContextInner);
|
||||
|
||||
impl std::fmt::Display for Context {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self.0 {
|
||||
ContextInner::String(ref s) => f.write_str(s),
|
||||
ContextInner::Compound(ref ctxs) => {
|
||||
let mut ctxs = ctxs.iter();
|
||||
if let Some(ctx) = ctxs.next() {
|
||||
write!(f, "{ctx}")?;
|
||||
for ctx in ctxs {
|
||||
write!(f, "\n{ctx}")?;
|
||||
impl fmt::Display for Context {
|
||||
#[inline(always)]
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum ContextInner {
|
||||
Elem(ContextElem),
|
||||
Compound(Vec<ContextElem>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum ContextElem {
|
||||
Str(&'static str),
|
||||
String(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for ContextInner {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Elem(elem) => fmt::Display::fmt(elem, f),
|
||||
Self::Compound(elems) => {
|
||||
let mut elems = elems.iter();
|
||||
if let Some(elem) = elems.next() {
|
||||
fmt::Display::fmt(elem, f)?;
|
||||
for elem in elems {
|
||||
write!(f, "\n{elem}")?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -22,10 +43,13 @@ impl std::fmt::Display for Context {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum ContextInner {
|
||||
String(Cow<'static, str>),
|
||||
Compound(Vec<Context>),
|
||||
impl fmt::Display for ContextElem {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Str(s) => f.write_str(s),
|
||||
Self::String(s) => f.write_str(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IntoContext {
|
||||
|
@ -49,34 +73,48 @@ impl IntoContext for Context {
|
|||
/// Chains another piece of context that is equal from a hierarchical perspective.
|
||||
#[inline]
|
||||
fn chain(self, other: impl IntoContext) -> Self {
|
||||
Context(ContextInner::Compound(match self {
|
||||
Context(ContextInner::Compound(mut items)) => {
|
||||
items.push(other.into_context());
|
||||
items
|
||||
Context(ContextInner::Compound(match self.0 {
|
||||
ContextInner::Compound(mut elems) => {
|
||||
match other.into_context().0 {
|
||||
ContextInner::Elem(elem) => elems.push(elem),
|
||||
ContextInner::Compound(mut elems1) => elems.append(&mut elems1),
|
||||
};
|
||||
elems
|
||||
}
|
||||
_ => vec![self, other.into_context()],
|
||||
ContextInner::Elem(elem) => {
|
||||
match other.into_context().0 {
|
||||
ContextInner::Elem(elem1) => vec![elem, elem1],
|
||||
ContextInner::Compound(mut elems) => {
|
||||
elems.insert(0, elem);
|
||||
elems
|
||||
}
|
||||
}
|
||||
},
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoContext for String {
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn into_context(self) -> Context {
|
||||
Context(ContextInner::String(self.into()))
|
||||
Context(ContextInner::Elem(ContextElem::String(self)))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoContext for &'static str {
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn into_context(self) -> Context {
|
||||
Context(ContextInner::String(self.into()))
|
||||
Context(ContextInner::Elem(ContextElem::Str(self)))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoContext for Cow<'static, str> {
|
||||
#[inline(always)]
|
||||
#[inline]
|
||||
fn into_context(self) -> Context {
|
||||
Context(ContextInner::String(self))
|
||||
match self {
|
||||
Cow::Borrowed(s) => s.into_context(),
|
||||
Cow::Owned(s) => s.into_context(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ where
|
|||
|
||||
#[inline(always)]
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
33
src/how.rs
33
src/how.rs
|
@ -15,18 +15,6 @@ struct HowInner {
|
|||
context: Vec<Context>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for How {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let mut b = f.debug_struct(std::any::type_name::<Self>());
|
||||
let b = b
|
||||
.field("classified", &self.0.classified)
|
||||
.field("context", &(&self.0.context));
|
||||
#[cfg(feature = "backtrace")]
|
||||
let b = b.field("backtrace", &self.0.backtrace);
|
||||
b.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl How {
|
||||
#[must_use]
|
||||
#[inline(never)]
|
||||
|
@ -65,6 +53,16 @@ impl How {
|
|||
pub const fn is_classified(&self) -> bool {
|
||||
self.0.classified
|
||||
}
|
||||
|
||||
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
|
||||
.field("classified", &self.0.classified)
|
||||
.field("context", &(&self.0.context));
|
||||
#[cfg(feature = "backtrace")]
|
||||
let b = b.field("backtrace", &self.0.backtrace);
|
||||
b.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl explain::Sealed for How {}
|
||||
|
@ -99,3 +97,14 @@ impl std::fmt::Display for How {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for How {
|
||||
#[inline(always)]
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if f.alternate() {
|
||||
self.fmt_debug_alternate(f)
|
||||
} else {
|
||||
std::fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ impl<T> IntoResultHow for Option<T> {
|
|||
fn into_result_how(self) -> Result<Self::T, How> {
|
||||
#[inline(never)]
|
||||
fn into() -> How {
|
||||
How::new("None")
|
||||
How::new("Option::None")
|
||||
}
|
||||
self.ok_or_else(into)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
#![forbid(unsafe_code)]
|
||||
#![feature(backtrace)]
|
||||
|
||||
mod sealed;
|
||||
pub(crate) use sealed::seal;
|
||||
|
|
Loading…
Reference in New Issue