Chayim Friedman's answer doesn't include adding the ellipsis.
Tweaking the implementation of fmt::Debug further to support this is not too tricky. I did it by adjusting their code to wrap the iterated values into an enum with a More value. The code can probably be cleaned up a bit.
use core::fmt::Formatter;
use std::fmt;
enum OrMore<T> {
Value(T),
More,
}
impl<T: fmt::Debug> fmt::Debug for OrMore<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
OrMore::Value(t) => fmt::Debug::fmt(t, f),
OrMore::More => write!(f, "..."),
}
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct LimitedVec<T>(pub Vec<T>);
const LIMIT: usize = 5;
impl<T: fmt::Debug> fmt::Debug for LimitedVec<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.0.len() <= LIMIT {
f.debug_list().entries(self.0.iter().take(LIMIT)).finish()
} else {
f.debug_list()
.entries(
self.0
.iter()
.take(LIMIT)
.map(OrMore::Value)
.chain(vec![OrMore::More].into_iter()),
)
.finish()
}
}
}
fn main() {
let w = LimitedVec(vec![1, 2, 3, 4, 5]);
let v = LimitedVec(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
println!("{:?}", w); // [1, 2, 3, 4, 5]
println!("{:?}", v); // [1, 2, 3, 4, 5, ...]
}
The code might be shorter if we used an explicit loop using write!(f, ...), rather than using the f.debug_list() approach, but IIRC that doesn't play well with the multi-line debug format {:#?}.