diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 11a2ed3b..dbcef82d 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -216,3 +216,41 @@ pub(crate) fn conduwuit_version() -> String { }, } } + +/// Debug-formats the given slice, but only up to the first `max_len` elements. +/// Any further elements are replaced by an ellipsis. +/// +/// See also [`debug_slice_truncated()`], +pub(crate) struct TruncatedDebugSlice<'a, T> { + inner: &'a [T], + max_len: usize, +} + +impl fmt::Debug for TruncatedDebugSlice<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.inner.len() <= self.max_len { + write!(f, "{:?}", self.inner) + } else { + f.debug_list() + .entries(&self.inner[..self.max_len]) + .entry(&"...") + .finish() + } + } +} + +/// See [`TruncatedDebugSlice`]. Useful for `#[instrument]`: +/// +/// ``` +/// #[tracing::instrument(fields( +/// foos = debug_slice_truncated(foos, N) +/// ))] +/// ``` +pub(crate) fn debug_slice_truncated( + slice: &[T], max_len: usize, +) -> tracing::field::DebugValue> { + tracing::field::debug(TruncatedDebugSlice { + inner: slice, + max_len, + }) +}