use std::borrow::Borrow;
use std::fmt::{self, Alignment, Display, Formatter};
use super::PrecisionBehavior;
pub trait CustomDisplay {
type Value: ?Sized;
fn fmt(&self, value: &Self::Value, f: &mut Formatter<'_>) -> fmt::Result;
fn precision_behavior(&self) -> PrecisionBehavior;
fn width_in_chars(&self, value: &Self::Value, f: &Formatter<'_>) -> Option<usize>;
#[inline]
fn auto_width_fill_alignment(&self) -> bool {
true
}
#[inline]
fn default_alignment(&self) -> Alignment {
Alignment::Left
}
#[inline]
fn display<'multi>(
&'multi self,
value: &'multi Self::Value,
) -> BorrowedDisplayable<'multi, Self> {
Displayable {
display: self,
value,
}
}
#[inline]
fn into_display(self, value: &Self::Value) -> OwnedDisplayable<'_, Self>
where
Self: Sized,
{
Displayable {
display: self,
value,
}
}
}
pub type BorrowedDisplayable<'multi, CD> = Displayable<'multi, CD, &'multi CD>;
pub type OwnedDisplayable<'value, CD> = Displayable<'value, CD, CD>;
#[derive(Clone, Copy, Debug)]
pub struct Displayable<'value, CD, B>
where
CD: CustomDisplay + ?Sized,
B: Borrow<CD>,
{
display: B,
value: &'value CD::Value,
}
impl<CD, B> Displayable<'_, CD, B>
where
CD: CustomDisplay + ?Sized,
B: Borrow<CD>,
{
#[expect(
clippy::inline_always,
reason = "exceedingly simple comparison; method exists to make code \
more readable, as comparison is verbose"
)]
#[inline(always)]
fn auto_truncate(&self) -> bool {
self.display.borrow().precision_behavior() == PrecisionBehavior::AutoTruncate
}
fn write_maybe_pre_formatted(
&self,
f: &mut Formatter<'_>,
pre_formatted: Option<String>,
) -> fmt::Result {
if let Some(formatted) = pre_formatted {
f.write_str(&formatted)
} else {
self.display.borrow().fmt(self.value, f)
}
}
}
#[expect(clippy::question_mark_used, reason = "format error propagation")]
fn write_fill(f: &mut Formatter<'_>, width: usize, fill: char) -> fmt::Result {
for _ in 0..width {
write!(f, "{fill}")?;
}
Ok(())
}
impl<CD, B> Display for Displayable<'_, CD, B>
where
CD: CustomDisplay + ?Sized,
B: Borrow<CD>,
{
#[expect(clippy::question_mark_used, reason = "format error propagation")]
#[expect(
clippy::arithmetic_side_effects,
reason = "subtracting guaranteed smaller values"
)]
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let display = self.display.borrow();
if display.auto_width_fill_alignment()
&& let Some(width) = f.width()
{
let (value_width, pre_formatted) = if self.auto_truncate()
&& let Some(precision) = f.precision()
{
if let Some(cheap_width) = display.width_in_chars(self.value, f)
&& cheap_width <= precision
{
(cheap_width, None)
} else {
#[expect(
clippy::recursive_format_impl,
reason = "recurses into case 3 from case 1a.2"
)]
let formatted = format!("{self}");
if (display.default_alignment() == Alignment::Left) || f.align().is_some() {
return f.pad(&formatted);
}
let truncated = format!("{formatted:.precision$}");
(truncated.chars().count(), Some(truncated))
}
} else if let Some(cheap_width) = display.width_in_chars(self.value, f) {
(cheap_width, None)
} else {
#[expect(
clippy::recursive_format_impl,
reason = "recurses into case 3 from case 1c"
)]
let formatted = format!("{self}");
(formatted.chars().count(), Some(formatted))
};
if value_width >= width {
self.write_maybe_pre_formatted(f, pre_formatted)
} else {
let total_fill = width - value_width;
let fill = f.fill();
match f.align().unwrap_or_else(|| display.default_alignment()) {
Alignment::Left => {
self.write_maybe_pre_formatted(f, pre_formatted)?;
write_fill(f, total_fill, fill)
}
Alignment::Right => {
write_fill(f, total_fill, fill)?;
self.write_maybe_pre_formatted(f, pre_formatted)
}
Alignment::Center => {
let left_fill = total_fill / 2;
let right_fill = total_fill - left_fill;
write_fill(f, left_fill, fill)?;
self.write_maybe_pre_formatted(f, pre_formatted)?;
write_fill(f, right_fill, fill)
}
}
}
} else if self.auto_truncate() && f.precision().is_some() {
#[expect(
clippy::recursive_format_impl,
reason = "recurses into case 3 from case 2"
)]
let formatted = format!("{self}");
f.pad(&formatted)
} else {
display.fmt(self.value, f)
}
}
}