exhibit 0.2.0

A small Rust library for controlling the display of any Displayable type
Documentation
use std::fmt;

use cfg_if::cfg_if;
#[cfg(feature = "unicode")]
use unicode_width::UnicodeWidthChar;

#[inline]
pub(super) fn writeln_untruncated(
    f: &mut fmt::Formatter,
    line: &str,
    redact: bool,
    strip_ansi: bool,
    shade_wide: bool,
) -> fmt::Result {
    write_untruncated(f, line, redact, strip_ansi, shade_wide)?;
    writeln!(f)
}

#[inline]
pub(super) fn writeln_truncated(
    f: &mut fmt::Formatter,
    line: &str,
    redact: bool,
    strip_ansi: bool,
    shade_wide: bool,
    mut width: usize,
) -> fmt::Result {
    write_truncated(f, line, redact, strip_ansi, shade_wide, &mut width)?;
    writeln!(f)
}

cfg_if! {
    if #[cfg(feature = "ansi")] {
        /// A helper function that applies different closure formatters
        /// to ANSI escape sequences and plain text chunks.
        #[inline]
        fn try_map_chunks(
            f: &mut fmt::Formatter,
            line: &str,
            strip_ansi: bool,
            mut ignore_ansi_fmt: impl FnMut(&mut fmt::Formatter, &str) -> fmt::Result,
            mut ansi_fmt: impl FnMut(&mut fmt::Formatter, &str) -> fmt::Result,
        ) -> fmt::Result {
            // The below can fail to strip ANSI escapes.
            let stripped_line_bytes = strip_ansi_escapes::strip(line).map_err(|_| fmt::Error)?;
            // The below can fail if the bytes are invalid UTF-8 after stripping escapes.
            let stripped_line = std::str::from_utf8(&stripped_line_bytes).map_err(|_| fmt::Error)?;

            if strip_ansi {
                ignore_ansi_fmt(f, stripped_line)
            } else {
                let diff = similar::TextDiff::configure()
                    .algorithm(similar::Algorithm::Myers)
                    .diff_chars(line, stripped_line);
                let remapper = similar::utils::TextDiffRemapper::from_text_diff(&diff, line, stripped_line);
                let mut iter = diff.ops().iter().flat_map(|x| remapper.iter_slices(x));

                iter.try_for_each(|(tag, chunk)| match tag {
                    similar::ChangeTag::Delete => ansi_fmt(f, chunk),
                    similar::ChangeTag::Equal => ignore_ansi_fmt(f, chunk),
                    similar::ChangeTag::Insert => unreachable!("ChangeTag::Insert should not be possible by construction"),
                })
            }
        }

        #[inline]
        fn write_untruncated(
            f: &mut fmt::Formatter,
            line: &str,
            redact: bool,
            strip_ansi: bool,
            shade_wide: bool,
        ) -> fmt::Result {
            if redact || strip_ansi {
                try_map_chunks(f, line, strip_ansi, |f, chunk| write_untruncated_ignore_ansi(f, chunk, redact, shade_wide), |f, chunk| write!(f, "{chunk}"))
            } else {
                write_untruncated_ignore_ansi(f, line, redact, shade_wide)
            }
        }

        #[inline]
        fn write_truncated(
            f: &mut fmt::Formatter,
            line: &str,
            redact: bool,
            strip_ansi: bool,
            shade_wide: bool,
            width: &mut usize,
        ) -> fmt::Result {
            try_map_chunks(f, line, strip_ansi, |f, chunk| write_truncated_ignore_ansi(f, chunk, redact, shade_wide, width), |f, chunk| write!(f, "{chunk}"))
        }
    } else {
        #[inline]
        fn write_untruncated(
            f: &mut fmt::Formatter,
            line: &str,
            redact: bool,
            _: bool,
            shade_wide: bool,
        ) -> fmt::Result {
            write_untruncated_ignore_ansi(f, line, redact, shade_wide)
        }

        #[inline]
        fn write_truncated(
            f: &mut fmt::Formatter,
            line: &str,
            redact: bool,
            _: bool,
            shade_wide: bool,
            width: &mut usize,
        ) -> fmt::Result {
            write_truncated_ignore_ansi(f, line, redact, shade_wide, width)
        }
    }
}

#[allow(unused_variables)]
#[inline]
fn write_untruncated_ignore_ansi(
    f: &mut fmt::Formatter,
    line: &str,
    redact: bool,
    shade_wide: bool,
) -> fmt::Result {
    cfg_if! {
        if #[cfg(feature = "unicode")] {
            let shade_wide = shade_wide;
        } else {
            let shade_wide = false;
        }
    }

    if redact || shade_wide {
        line.chars()
            .try_for_each(|c| write_char(f, c, redact, shade_wide))
    } else {
        write!(f, "{line}")
    }
}

#[inline]
fn write_truncated_ignore_ansi(
    f: &mut fmt::Formatter,
    line: &str,
    redact: bool,
    shade_wide: bool,
    width: &mut usize,
) -> fmt::Result {
    line.chars()
        .take(*width)
        .take_while(|c| should_write_char(*c, width))
        .try_for_each(|c| write_char(f, c, redact, shade_wide))
}

#[allow(unused_variables)]
#[inline]
fn should_write_char(c: char, width: &mut usize) -> bool {
    if *width == 0 {
        return false;
    }

    cfg_if! {
        if #[cfg(feature = "unicode")] {
            let cw = c.width().unwrap_or(1);
            if *width < cw {
                return false;
            }

            *width -= cw;
        } else {
            *width -= 1;
        }
    }

    true
}

#[inline]
fn should_redact_char(c: char) -> bool {
    !c.is_whitespace() && !c.is_ascii_punctuation()
}

#[allow(unused_variables)]
#[inline]
fn write_char(f: &mut fmt::Formatter, c: char, redact: bool, shade_wide: bool) -> fmt::Result {
    cfg_if! {
        if #[cfg(feature = "unicode")] {
            if redact || shade_wide {
                let cw = c.width().unwrap_or(1);
                if cw > 1 {
                    return (0..cw).try_for_each(|_| if redact {
                        write!(f, "{}", '')
                    } else {
                        write!(f, "{}", '')
                    });
                }
            }
        }
    }

    if redact && should_redact_char(c) {
        // Make 'Q' seem slightly longer than other uppercase letters.
        if c == 'Q' {
            return write!(f, "");
        }

        // Uppercase letters or "tall" lowercase letters.
        if c.is_uppercase() || "bdfhijklt".contains(c) {
            return write!(f, "");
        }

        // Lowercase characters that roughly fit into a square.
        return write!(f, "");
    }

    write!(f, "{c}")
}