erratic 0.11.1

Handling errors in an efficient way.
Documentation
use core::{
    error::{self},
    fmt::{self, Debug, Display, Write},
    result,
};

use alloc::string::String;

use crate::backtrace::Backtrace;

struct DisplayAsDebug<'a>(pub &'a dyn Display);

impl<'a> Debug for DisplayAsDebug<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, r#""{}""#, self.0)
    }
}

fn format_state_context_payload(
    f: &mut fmt::Formatter<'_>,
    state: Option<&impl Debug>,
    context: Option<&impl Display>,
    payload: Option<&impl Display>,
) -> result::Result<bool, fmt::Error> {
    let context_payload = match (context, payload) {
        (None, None) => None,
        (None, Some(payload)) => Some(format_args!("{}", *payload)),
        (Some(context), None) => Some(format_args!("{}", *context)),
        (Some(context), Some(payload)) => Some(format_args!("{}{}", *context, *payload)),
    };
    match (state, context_payload) {
        (None, None) => return Ok(false),
        (None, Some(context_payload)) => {
            write!(f, "{}", context_payload)?;
        }
        (Some(state), None) => {
            write!(f, "{state:?}")?;
        }
        (Some(state), Some(context_payload)) => {
            write!(f, "{:?}: {}", state, context_payload)?;
        }
    }
    Ok(true)
}

pub fn format_debug<S>(
    f: &mut fmt::Formatter<'_>,
    container_name: &'static str,
    state: Option<&S>,
    context: Option<&(dyn Display + Send + Sync + 'static)>,
    payload: Option<&(dyn Display + Send + Sync + 'static)>,
    source: Option<&(dyn error::Error + 'static)>,
    backtrace: Option<&dyn Backtrace>,
) -> fmt::Result
where
    S: Debug + 'static,
{
    let show_less = f.sign_minus();

    if f.alternate() {
        let ds = &mut f.debug_struct(container_name);

        if let Some(state) = state {
            ds.field("state", state);
        }

        if let Some(context) = context {
            ds.field("context", &DisplayAsDebug(context));
        }

        if let Some(payload) = payload {
            ds.field("payload", &DisplayAsDebug(payload));
        }

        if let Some(source) = source {
            ds.field("source", source);
        }

        if !show_less && let Some(backtrace) = backtrace {
            ds.field("backtrace", &backtrace);
        }

        ds.finish()
    } else {
        let mut source = source;
        let has_additional_info =
            format_state_context_payload(f, state, context.as_ref(), payload.as_ref())?;
        let mut dedup = DedupLast::new();

        if !has_additional_info {
            let Some(err) = source else {
                unreachable!();
            };
            write!(dedup.format_one(f), "{err}")?;
            source = err.source();
        }

        while let Some(err) = source {
            write!(f, "\n  -> ")?;
            write!(dedup.format_one(f), "{err}")?;
            source = err.source();
        }

        if !show_less && let Some(backtrace) = backtrace {
            write!(f, "\nBacktrace:\n")?;
            write!(f, "{backtrace}")?;
        }

        Ok(())
    }
}

pub fn format_display<S>(
    f: &mut fmt::Formatter<'_>,
    state: Option<&S>,
    context: Option<&dyn Display>,
    payload: Option<&dyn Display>,
    source: Option<&(dyn error::Error + 'static)>,
    _backtrace: Option<&dyn Backtrace>,
) -> fmt::Result
where
    S: Debug + 'static,
{
    if f.alternate() {
        let mut source = source;
        let has_additional_info =
            format_state_context_payload(f, state, context.as_ref(), payload.as_ref())?;
        let mut dedup = DedupLast::new();

        if !has_additional_info {
            let Some(err) = source else {
                unreachable!();
            };
            write!(dedup.format_one(f), "{err}")?;
            source = err.source();
        }

        while let Some(err) = source {
            write!(f, "\n  -> ")?;
            write!(dedup.format_one(f), "{err}")?;
            source = err.source();
        }
    } else {
        let has_additional_info =
            format_state_context_payload(f, state, context.as_ref(), payload.as_ref())?;

        if !has_additional_info {
            let Some(err) = source else {
                unreachable!();
            };
            Display::fmt(err, f)?;
        }
    }

    Ok(())
}

struct DedupLast {
    last: String,
}

impl DedupLast {
    fn new() -> Self {
        Self {
            last: String::new(),
        }
    }

    fn format_one<'a, 'b>(&'a mut self, f: &'a mut fmt::Formatter<'b>) -> FormatOne<'a, 'b> {
        FormatOne {
            formatter: f,
            last: &mut self.last,
            index: Some(0),
        }
    }
}

struct FormatOne<'a, 'b> {
    formatter: &'a mut fmt::Formatter<'b>,
    last: &'a mut String,
    index: Option<usize>,
}

impl<'a, 'b> Write for FormatOne<'a, 'b> {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        let Some(index) = self.index.as_mut() else {
            self.last.push_str(s);
            return self.formatter.write_str(s);
        };

        if let Some((_, last)) = self.last.split_at_checked(*index)
            && last.starts_with(s)
        {
            *index += s.len();
            return Ok(());
        }

        self.last.truncate(*index);
        self.index = None;

        self.formatter.write_str(self.last)?;
        Write::write_str(self, s)
    }
}