use core::fmt::{Debug, Formatter};
#[derive(Clone, Copy)]
pub struct DebugArray<'a, T: Debug>(&'a [T], bool, Option<&'a [T]>);
impl<'a, T: Debug> DebugArray<'a, T> {
pub const fn debug(
array: &'a [T],
non_exhaustive: bool,
continuation: Option<&'a [T]>,
) -> DebugArrayDebugger<'a, T> {
DebugArrayDebugger(Self(array, non_exhaustive, continuation))
}
}
impl<'a, T: Debug> Debug for DebugArray<'a, T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut ret = f.debug_list();
let mut ret = ret.entries(self.0);
if self.1 || self.2.is_some() {
ret = ret.entry(&..);
}
if let Some(v) = self.2 {
ret = ret.entries(v);
}
ret.finish()
}
}
#[repr(transparent)]
pub struct DebugArrayDebugger<'a, T: Debug>(DebugArray<'a, T>);
impl<'a, T: Debug> Debug for DebugArrayDebugger<'a, T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{:?}", self.0))
}
}
pub trait ArrayDebug<'a, T: Debug>
where
Self: Sized,
{
fn into_debug_array(self, first_elems: usize, last_elems: usize) -> DebugArray<'a, T>;
fn array_debug(self, first_elems: usize, last_elems: usize) -> DebugArrayDebugger<'a, T> {
DebugArrayDebugger(self.into_debug_array(first_elems, last_elems))
}
}
impl<'a, T: Debug> ArrayDebug<'a, T> for &'a [T] {
#[allow(clippy::indexing_slicing)]
fn into_debug_array(self, mut first_elems: usize, mut last_elems: usize) -> DebugArray<'a, T> {
let len = self.len();
if last_elems > len {
last_elems = 0;
}
let non_exhaustive = if first_elems >= len {
first_elems = len;
last_elems = 0;
false
} else {
true
};
let first_elems = &self[..first_elems];
#[allow(clippy::arithmetic_side_effects)]
let last_elems = match &self[len - last_elems..] {
&[] => None,
v => Some(v),
};
DebugArray(first_elems, non_exhaustive, last_elems)
}
}