1use std::fmt;
16
17pub struct DisplaySlice<'a, T: fmt::Display> {
22 slice: &'a [T],
23 limit: Option<usize>,
25 separator: &'a str,
27}
28
29impl<'a, T: fmt::Display> DisplaySlice<'a, T> {
30 pub fn new(slice: &'a [T]) -> Self {
31 Self {
32 slice,
33 limit: None,
34 separator: ",",
35 }
36 }
37
38 pub fn at_most(mut self, limit: Option<usize>) -> Self {
39 self.limit = limit;
40 self
41 }
42
43 pub fn sep(mut self, separator: &'a str) -> Self {
44 self.separator = separator;
45 self
46 }
47
48 pub fn limit(&self) -> usize {
49 self.limit.unwrap_or(5)
50 }
51}
52
53impl<T: fmt::Display> fmt::Display for DisplaySlice<'_, T> {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 let limit = self.limit();
56
57 if limit == 0 {
58 return write!(f, "[..]");
59 }
60
61 let slice = self.slice;
62 let len = slice.len();
63
64 write!(f, "[")?;
65
66 let sep = self.separator;
67
68 if len > limit {
69 for t in slice[..(limit - 1)].iter() {
70 write!(f, "{}{}", t, sep)?;
71 }
72
73 write!(f, "..{}", sep)?;
74 write!(f, "{}", slice.last().unwrap())?;
75 } else {
76 for (i, t) in slice.iter().enumerate() {
77 if i > 0 {
78 write!(f, "{}", sep)?;
79 }
80
81 write!(f, "{}", t)?;
82 }
83 }
84
85 write!(f, "]")
86 }
87}
88
89pub trait DisplaySliceExt<'a, T: fmt::Display> {
103 fn display(&'a self) -> DisplaySlice<'a, T>;
104
105 fn display_n(&'a self, n: usize) -> DisplaySlice<'a, T> {
107 self.display().at_most(Some(n))
108 }
109}
110
111impl<T> DisplaySliceExt<'_, T> for [T]
112where T: fmt::Display
113{
114 fn display(&self) -> DisplaySlice<T> {
115 DisplaySlice::new(self)
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::DisplaySlice;
122 use crate::DisplaySliceExt;
123
124 #[test]
125 fn test_display_slice() {
126 let a = vec![1, 2, 3, 4];
127 assert_eq!("[1,2,3,4]", DisplaySlice::new(&a).to_string());
128
129 let a = vec![1, 2, 3, 4, 5];
130 assert_eq!("[1,2,3,4,5]", DisplaySlice::new(&a).to_string());
131
132 let a = vec![1, 2, 3, 4, 5, 6];
133 assert_eq!("[1,2,3,4,..,6]", DisplaySlice::new(&a).to_string());
134
135 let a = vec![1, 2, 3, 4, 5, 6, 7];
136 assert_eq!("[1,2,3,4,..,7]", DisplaySlice::new(&a).to_string());
137
138 let a = vec![1, 2, 3, 4, 5, 6, 7];
141 assert_eq!(
142 "[1,..,7]",
143 DisplaySlice::new(&a).at_most(Some(2)).to_string()
144 );
145
146 assert_eq!("[1,..,7]", a.display().at_most(Some(2)).to_string());
147
148 assert_eq!("[1,..,7]", a.display_n(2).to_string());
149
150 assert_eq!("[..,7]", a.display_n(1).to_string());
151
152 assert_eq!("[..]", a.display_n(0).to_string());
153 }
154
155 #[test]
156 fn test_display_slice_separator() {
157 let a = vec![1, 2, 3];
158 assert_eq!("[1, 2, 3]", a.display().sep(", ").to_string());
159
160 let a = vec![1, 2, 3, 4, 5, 6];
161 assert_eq!("[1, 2, 3, 4, .., 6]", a.display().sep(", ").to_string());
162
163 assert_eq!("[1|..|6]", a.display_n(2).sep("|").to_string());
164
165 assert_eq!("[1 2 3 4 .. 6]", a.display().sep(" ").to_string());
166
167 assert_eq!("[1234..6]", a.display().sep("").to_string());
168 assert_eq!("[1..6]", a.display_n(2).sep("").to_string());
169
170 assert_eq!("[.. 6]", a.display_n(1).sep(" ").to_string());
172
173 assert_eq!("[..]", a.display_n(0).sep(" ").to_string());
175 }
176}