1use super::{ArrayBase, ArrayView, Axis, Data, Dimension, NdProducer};
9use crate::aliases::{Ix1, IxDyn};
10use alloc::format;
11use std::fmt;
12
13const ARRAY_MANY_ELEMENT_LIMIT: usize = 500;
15const AXIS_LIMIT_STACKED: usize = 6;
17const AXIS_LIMIT_COL: usize = 11;
20const AXIS_LIMIT_ROW: usize = 11;
23
24#[cfg(test)]
25const AXIS_2D_OVERFLOW_LIMIT: usize = 22;
27
28const ELLIPSIS: &str = "...";
30
31#[derive(Clone, Debug)]
32struct FormatOptions
33{
34 axis_collapse_limit: usize,
35 axis_collapse_limit_next_last: usize,
36 axis_collapse_limit_last: usize,
37}
38
39impl FormatOptions
40{
41 pub(crate) fn default_for_array(nelem: usize, no_limit: bool) -> Self
42 {
43 let default = Self {
44 axis_collapse_limit: AXIS_LIMIT_STACKED,
45 axis_collapse_limit_next_last: AXIS_LIMIT_COL,
46 axis_collapse_limit_last: AXIS_LIMIT_ROW,
47 };
48 default.set_no_limit(no_limit || nelem < ARRAY_MANY_ELEMENT_LIMIT)
49 }
50
51 fn set_no_limit(mut self, no_limit: bool) -> Self
52 {
53 if no_limit {
54 self.axis_collapse_limit = usize::MAX;
55 self.axis_collapse_limit_next_last = usize::MAX;
56 self.axis_collapse_limit_last = usize::MAX;
57 }
58 self
59 }
60
61 pub(crate) fn collapse_limit(&self, axis_rindex: usize) -> usize
64 {
65 match axis_rindex {
66 0 => self.axis_collapse_limit_last,
67 1 => self.axis_collapse_limit_next_last,
68 _ => self.axis_collapse_limit,
69 }
70 }
71}
72
73fn format_with_overflow(
86 f: &mut fmt::Formatter<'_>, length: usize, limit: usize, separator: &str, ellipsis: &str,
87 fmt_elem: &mut dyn FnMut(&mut fmt::Formatter, usize) -> fmt::Result,
88) -> fmt::Result
89{
90 if length == 0 {
91 } else if length <= limit {
93 fmt_elem(f, 0)?;
94 for i in 1..length {
95 f.write_str(separator)?;
96 fmt_elem(f, i)?
97 }
98 } else {
99 let edge = limit / 2;
100 fmt_elem(f, 0)?;
101 for i in 1..edge {
102 f.write_str(separator)?;
103 fmt_elem(f, i)?;
104 }
105 f.write_str(separator)?;
106 f.write_str(ellipsis)?;
107 for i in length - edge..length {
108 f.write_str(separator)?;
109 fmt_elem(f, i)?
110 }
111 }
112 Ok(())
113}
114
115fn format_array<A, S, D, F>(
116 array: &ArrayBase<S, D>, f: &mut fmt::Formatter<'_>, format: F, fmt_opt: &FormatOptions,
117) -> fmt::Result
118where
119 F: FnMut(&A, &mut fmt::Formatter<'_>) -> fmt::Result + Clone,
120 D: Dimension,
121 S: Data<Elem = A>,
122{
123 format_array_inner(array.view().into_dyn(), f, format, fmt_opt, 0, array.ndim())
126}
127
128fn format_array_inner<A, F>(
129 view: ArrayView<A, IxDyn>, f: &mut fmt::Formatter<'_>, mut format: F, fmt_opt: &FormatOptions, depth: usize,
130 full_ndim: usize,
131) -> fmt::Result
132where
133 F: FnMut(&A, &mut fmt::Formatter<'_>) -> fmt::Result + Clone,
134{
135 if view.is_empty() {
138 write!(f, "{}{}", "[".repeat(view.ndim()), "]".repeat(view.ndim()))?;
139 return Ok(());
140 }
141 match view.shape() {
142 &[] => format(&view[[]], f)?,
144 &[len] => {
146 let view = view.view().into_dimensionality::<Ix1>().unwrap();
147 f.write_str("[")?;
148 format_with_overflow(f, len, fmt_opt.collapse_limit(0), ", ", ELLIPSIS, &mut |f, index| {
149 format(&view[index], f)
150 })?;
151 f.write_str("]")?;
152 }
153 shape => {
155 let blank_lines = "\n".repeat(shape.len() - 2);
156 let indent = " ".repeat(depth + 1);
157 let separator = format!(",\n{}{}", blank_lines, indent);
158
159 f.write_str("[")?;
160 let limit = fmt_opt.collapse_limit(full_ndim - depth - 1);
161 format_with_overflow(f, shape[0], limit, &separator, ELLIPSIS, &mut |f, index| {
162 format_array_inner(view.index_axis(Axis(0), index), f, format.clone(), fmt_opt, depth + 1, full_ndim)
163 })?;
164 f.write_str("]")?;
165 }
166 }
167 Ok(())
168}
169
170impl<A: fmt::Display, S, D: Dimension> fmt::Display for ArrayBase<S, D>
176where S: Data<Elem = A>
177{
178 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
179 {
180 let fmt_opt = FormatOptions::default_for_array(self.len(), f.alternate());
181 format_array(self, f, <_>::fmt, &fmt_opt)
182 }
183}
184
185impl<A: fmt::Debug, S, D: Dimension> fmt::Debug for ArrayBase<S, D>
190where S: Data<Elem = A>
191{
192 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
193 {
194 let fmt_opt = FormatOptions::default_for_array(self.len(), f.alternate());
195 format_array(self, f, <_>::fmt, &fmt_opt)?;
196
197 write!(
199 f,
200 ", shape={:?}, strides={:?}, layout={:?}",
201 self.shape(),
202 self.strides(),
203 self.view().layout(),
204 )?;
205 match D::NDIM {
206 Some(ndim) => write!(f, ", const ndim={}", ndim)?,
207 None => write!(f, ", dynamic ndim={}", self.ndim())?,
208 }
209 Ok(())
210 }
211}
212
213impl<A: fmt::LowerExp, S, D: Dimension> fmt::LowerExp for ArrayBase<S, D>
218where S: Data<Elem = A>
219{
220 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
221 {
222 let fmt_opt = FormatOptions::default_for_array(self.len(), f.alternate());
223 format_array(self, f, <_>::fmt, &fmt_opt)
224 }
225}
226
227impl<A: fmt::UpperExp, S, D: Dimension> fmt::UpperExp for ArrayBase<S, D>
232where S: Data<Elem = A>
233{
234 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
235 {
236 let fmt_opt = FormatOptions::default_for_array(self.len(), f.alternate());
237 format_array(self, f, <_>::fmt, &fmt_opt)
238 }
239}
240impl<A: fmt::LowerHex, S, D: Dimension> fmt::LowerHex for ArrayBase<S, D>
245where S: Data<Elem = A>
246{
247 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
248 {
249 let fmt_opt = FormatOptions::default_for_array(self.len(), f.alternate());
250 format_array(self, f, <_>::fmt, &fmt_opt)
251 }
252}
253
254impl<A: fmt::Binary, S, D: Dimension> fmt::Binary for ArrayBase<S, D>
259where S: Data<Elem = A>
260{
261 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
262 {
263 let fmt_opt = FormatOptions::default_for_array(self.len(), f.alternate());
264 format_array(self, f, <_>::fmt, &fmt_opt)
265 }
266}
267
268#[cfg(test)]
269mod formatting_with_omit
270{
271 #[cfg(not(feature = "std"))]
272 use alloc::string::String;
273 #[cfg(not(feature = "std"))]
274 use alloc::vec::Vec;
275 use itertools::Itertools;
276
277 use super::*;
278 use crate::prelude::*;
279
280 fn assert_str_eq(expected: &str, actual: &str)
281 {
282 assert!(
284 expected == actual,
285 "formatting assertion failed\nexpected:\n{}\nactual:\n{}\n",
286 expected,
287 actual,
288 );
289 }
290
291 fn ellipsize(limit: usize, sep: &str, elements: impl IntoIterator<Item = impl fmt::Display>) -> String
292 {
293 let elements = elements.into_iter().collect::<Vec<_>>();
294 let edge = limit / 2;
295 if elements.len() <= limit {
296 format!("{}", elements.iter().format(sep))
297 } else {
298 format!(
299 "{}{}{}{}{}",
300 elements[..edge].iter().format(sep),
301 sep,
302 ELLIPSIS,
303 sep,
304 elements[elements.len() - edge..].iter().format(sep)
305 )
306 }
307 }
308
309 #[test]
310 fn empty_arrays()
311 {
312 let a: Array2<u32> = arr2(&[[], []]);
313 let actual = format!("{}", a);
314 let expected = "[[]]";
315 assert_str_eq(expected, &actual);
316 }
317
318 #[test]
319 fn zero_length_axes()
320 {
321 let a = Array3::<f32>::zeros((3, 0, 4));
322 let actual = format!("{}", a);
323 let expected = "[[[]]]";
324 assert_str_eq(expected, &actual);
325 }
326
327 #[test]
328 fn dim_0()
329 {
330 let element = 12;
331 let a = arr0(element);
332 let actual = format!("{}", a);
333 let expected = "12";
334 assert_str_eq(expected, &actual);
335 }
336
337 #[test]
338 fn dim_1()
339 {
340 let overflow: usize = 2;
341 let a = Array1::from_elem(ARRAY_MANY_ELEMENT_LIMIT + overflow, 1);
342 let actual = format!("{}", a);
343 let expected = format!("[{}]", ellipsize(AXIS_LIMIT_ROW, ", ", a.iter()));
344 assert_str_eq(&expected, &actual);
345 }
346
347 #[test]
348 fn dim_1_alternate()
349 {
350 let overflow: usize = 2;
351 let a = Array1::from_elem(ARRAY_MANY_ELEMENT_LIMIT + overflow, 1);
352 let actual = format!("{:#}", a);
353 let expected = format!("[{}]", a.iter().format(", "));
354 assert_str_eq(&expected, &actual);
355 }
356
357 #[test]
358 fn dim_2_last_axis_overflow()
359 {
360 let overflow: usize = 2;
361 let a = Array2::from_elem((AXIS_2D_OVERFLOW_LIMIT, AXIS_2D_OVERFLOW_LIMIT + overflow), 1);
362 let actual = format!("{}", a);
363 let expected = "\
364[[1, 1, 1, 1, 1, ..., 1, 1, 1, 1, 1],
365 [1, 1, 1, 1, 1, ..., 1, 1, 1, 1, 1],
366 [1, 1, 1, 1, 1, ..., 1, 1, 1, 1, 1],
367 [1, 1, 1, 1, 1, ..., 1, 1, 1, 1, 1],
368 [1, 1, 1, 1, 1, ..., 1, 1, 1, 1, 1],
369 ...,
370 [1, 1, 1, 1, 1, ..., 1, 1, 1, 1, 1],
371 [1, 1, 1, 1, 1, ..., 1, 1, 1, 1, 1],
372 [1, 1, 1, 1, 1, ..., 1, 1, 1, 1, 1],
373 [1, 1, 1, 1, 1, ..., 1, 1, 1, 1, 1],
374 [1, 1, 1, 1, 1, ..., 1, 1, 1, 1, 1]]";
375 assert_str_eq(expected, &actual);
376 }
377
378 #[test]
379 fn dim_2_non_last_axis_overflow()
380 {
381 let a = Array2::from_elem((ARRAY_MANY_ELEMENT_LIMIT / 10, 10), 1);
382 let actual = format!("{}", a);
383 let row = format!("{}", a.row(0));
384 let expected = format!(
385 "[{}]",
386 ellipsize(AXIS_LIMIT_COL, ",\n ", (0..a.nrows()).map(|_| &row))
387 );
388 assert_str_eq(&expected, &actual);
389 }
390
391 #[test]
392 fn dim_2_non_last_axis_overflow_alternate()
393 {
394 let a = Array2::from_elem((AXIS_LIMIT_COL * 4, 6), 1);
395 let actual = format!("{:#}", a);
396 let row = format!("{}", a.row(0));
397 let expected = format!("[{}]", (0..a.nrows()).map(|_| &row).format(",\n "));
398 assert_str_eq(&expected, &actual);
399 }
400
401 #[test]
402 fn dim_2_multi_directional_overflow()
403 {
404 let overflow: usize = 2;
405 let a = Array2::from_elem((AXIS_2D_OVERFLOW_LIMIT + overflow, AXIS_2D_OVERFLOW_LIMIT + overflow), 1);
406 let actual = format!("{}", a);
407 let row = format!("[{}]", ellipsize(AXIS_LIMIT_ROW, ", ", a.row(0)));
408 let expected = format!(
409 "[{}]",
410 ellipsize(AXIS_LIMIT_COL, ",\n ", (0..a.nrows()).map(|_| &row))
411 );
412 assert_str_eq(&expected, &actual);
413 }
414
415 #[test]
416 fn dim_2_multi_directional_overflow_alternate()
417 {
418 let overflow: usize = 2;
419 let a = Array2::from_elem((AXIS_2D_OVERFLOW_LIMIT + overflow, AXIS_2D_OVERFLOW_LIMIT + overflow), 1);
420 let actual = format!("{:#}", a);
421 let row = format!("{}", a.row(0));
422 let expected = format!("[{}]", (0..a.nrows()).map(|_| &row).format(",\n "));
423 assert_str_eq(&expected, &actual);
424 }
425
426 #[test]
427 fn dim_3_overflow_most()
428 {
429 let a = Array3::from_shape_fn((AXIS_LIMIT_STACKED + 1, AXIS_LIMIT_COL, AXIS_LIMIT_ROW + 1), |(i, j, k)| {
430 1000. + (100. * ((i as f64).sqrt() + (j as f64).sin() + k as f64)).round() / 100.
431 });
432 let actual = format!("{:6.1}", a);
433 let expected = "\
434[[[1000.0, 1001.0, 1002.0, 1003.0, 1004.0, ..., 1007.0, 1008.0, 1009.0, 1010.0, 1011.0],
435 [1000.8, 1001.8, 1002.8, 1003.8, 1004.8, ..., 1007.8, 1008.8, 1009.8, 1010.8, 1011.8],
436 [1000.9, 1001.9, 1002.9, 1003.9, 1004.9, ..., 1007.9, 1008.9, 1009.9, 1010.9, 1011.9],
437 [1000.1, 1001.1, 1002.1, 1003.1, 1004.1, ..., 1007.1, 1008.1, 1009.1, 1010.1, 1011.1],
438 [ 999.2, 1000.2, 1001.2, 1002.2, 1003.2, ..., 1006.2, 1007.2, 1008.2, 1009.2, 1010.2],
439 [ 999.0, 1000.0, 1001.0, 1002.0, 1003.0, ..., 1006.0, 1007.0, 1008.0, 1009.0, 1010.0],
440 [ 999.7, 1000.7, 1001.7, 1002.7, 1003.7, ..., 1006.7, 1007.7, 1008.7, 1009.7, 1010.7],
441 [1000.7, 1001.7, 1002.7, 1003.7, 1004.7, ..., 1007.7, 1008.7, 1009.7, 1010.7, 1011.7],
442 [1001.0, 1002.0, 1003.0, 1004.0, 1005.0, ..., 1008.0, 1009.0, 1010.0, 1011.0, 1012.0],
443 [1000.4, 1001.4, 1002.4, 1003.4, 1004.4, ..., 1007.4, 1008.4, 1009.4, 1010.4, 1011.4],
444 [ 999.5, 1000.5, 1001.5, 1002.5, 1003.5, ..., 1006.5, 1007.5, 1008.5, 1009.5, 1010.5]],
445
446 [[1001.0, 1002.0, 1003.0, 1004.0, 1005.0, ..., 1008.0, 1009.0, 1010.0, 1011.0, 1012.0],
447 [1001.8, 1002.8, 1003.8, 1004.8, 1005.8, ..., 1008.8, 1009.8, 1010.8, 1011.8, 1012.8],
448 [1001.9, 1002.9, 1003.9, 1004.9, 1005.9, ..., 1008.9, 1009.9, 1010.9, 1011.9, 1012.9],
449 [1001.1, 1002.1, 1003.1, 1004.1, 1005.1, ..., 1008.1, 1009.1, 1010.1, 1011.1, 1012.1],
450 [1000.2, 1001.2, 1002.2, 1003.2, 1004.2, ..., 1007.2, 1008.2, 1009.2, 1010.2, 1011.2],
451 [1000.0, 1001.0, 1002.0, 1003.0, 1004.0, ..., 1007.0, 1008.0, 1009.0, 1010.0, 1011.0],
452 [1000.7, 1001.7, 1002.7, 1003.7, 1004.7, ..., 1007.7, 1008.7, 1009.7, 1010.7, 1011.7],
453 [1001.7, 1002.7, 1003.7, 1004.7, 1005.7, ..., 1008.7, 1009.7, 1010.7, 1011.7, 1012.7],
454 [1002.0, 1003.0, 1004.0, 1005.0, 1006.0, ..., 1009.0, 1010.0, 1011.0, 1012.0, 1013.0],
455 [1001.4, 1002.4, 1003.4, 1004.4, 1005.4, ..., 1008.4, 1009.4, 1010.4, 1011.4, 1012.4],
456 [1000.5, 1001.5, 1002.5, 1003.5, 1004.5, ..., 1007.5, 1008.5, 1009.5, 1010.5, 1011.5]],
457
458 [[1001.4, 1002.4, 1003.4, 1004.4, 1005.4, ..., 1008.4, 1009.4, 1010.4, 1011.4, 1012.4],
459 [1002.3, 1003.3, 1004.3, 1005.3, 1006.3, ..., 1009.3, 1010.3, 1011.3, 1012.3, 1013.3],
460 [1002.3, 1003.3, 1004.3, 1005.3, 1006.3, ..., 1009.3, 1010.3, 1011.3, 1012.3, 1013.3],
461 [1001.6, 1002.6, 1003.6, 1004.6, 1005.6, ..., 1008.6, 1009.6, 1010.6, 1011.6, 1012.6],
462 [1000.7, 1001.7, 1002.7, 1003.7, 1004.7, ..., 1007.7, 1008.7, 1009.7, 1010.7, 1011.7],
463 [1000.5, 1001.5, 1002.5, 1003.5, 1004.5, ..., 1007.5, 1008.5, 1009.5, 1010.5, 1011.5],
464 [1001.1, 1002.1, 1003.1, 1004.1, 1005.1, ..., 1008.1, 1009.1, 1010.1, 1011.1, 1012.1],
465 [1002.1, 1003.1, 1004.1, 1005.1, 1006.1, ..., 1009.1, 1010.1, 1011.1, 1012.1, 1013.1],
466 [1002.4, 1003.4, 1004.4, 1005.4, 1006.4, ..., 1009.4, 1010.4, 1011.4, 1012.4, 1013.4],
467 [1001.8, 1002.8, 1003.8, 1004.8, 1005.8, ..., 1008.8, 1009.8, 1010.8, 1011.8, 1012.8],
468 [1000.9, 1001.9, 1002.9, 1003.9, 1004.9, ..., 1007.9, 1008.9, 1009.9, 1010.9, 1011.9]],
469
470 ...,
471
472 [[1002.0, 1003.0, 1004.0, 1005.0, 1006.0, ..., 1009.0, 1010.0, 1011.0, 1012.0, 1013.0],
473 [1002.8, 1003.8, 1004.8, 1005.8, 1006.8, ..., 1009.8, 1010.8, 1011.8, 1012.8, 1013.8],
474 [1002.9, 1003.9, 1004.9, 1005.9, 1006.9, ..., 1009.9, 1010.9, 1011.9, 1012.9, 1013.9],
475 [1002.1, 1003.1, 1004.1, 1005.1, 1006.1, ..., 1009.1, 1010.1, 1011.1, 1012.1, 1013.1],
476 [1001.2, 1002.2, 1003.2, 1004.2, 1005.2, ..., 1008.2, 1009.2, 1010.2, 1011.2, 1012.2],
477 [1001.0, 1002.0, 1003.0, 1004.0, 1005.0, ..., 1008.0, 1009.0, 1010.0, 1011.0, 1012.0],
478 [1001.7, 1002.7, 1003.7, 1004.7, 1005.7, ..., 1008.7, 1009.7, 1010.7, 1011.7, 1012.7],
479 [1002.7, 1003.7, 1004.7, 1005.7, 1006.7, ..., 1009.7, 1010.7, 1011.7, 1012.7, 1013.7],
480 [1003.0, 1004.0, 1005.0, 1006.0, 1007.0, ..., 1010.0, 1011.0, 1012.0, 1013.0, 1014.0],
481 [1002.4, 1003.4, 1004.4, 1005.4, 1006.4, ..., 1009.4, 1010.4, 1011.4, 1012.4, 1013.4],
482 [1001.5, 1002.5, 1003.5, 1004.5, 1005.5, ..., 1008.5, 1009.5, 1010.5, 1011.5, 1012.5]],
483
484 [[1002.2, 1003.2, 1004.2, 1005.2, 1006.2, ..., 1009.2, 1010.2, 1011.2, 1012.2, 1013.2],
485 [1003.1, 1004.1, 1005.1, 1006.1, 1007.1, ..., 1010.1, 1011.1, 1012.1, 1013.1, 1014.1],
486 [1003.1, 1004.1, 1005.1, 1006.1, 1007.1, ..., 1010.1, 1011.1, 1012.1, 1013.1, 1014.1],
487 [1002.4, 1003.4, 1004.4, 1005.4, 1006.4, ..., 1009.4, 1010.4, 1011.4, 1012.4, 1013.4],
488 [1001.5, 1002.5, 1003.5, 1004.5, 1005.5, ..., 1008.5, 1009.5, 1010.5, 1011.5, 1012.5],
489 [1001.3, 1002.3, 1003.3, 1004.3, 1005.3, ..., 1008.3, 1009.3, 1010.3, 1011.3, 1012.3],
490 [1002.0, 1003.0, 1004.0, 1005.0, 1006.0, ..., 1009.0, 1010.0, 1011.0, 1012.0, 1013.0],
491 [1002.9, 1003.9, 1004.9, 1005.9, 1006.9, ..., 1009.9, 1010.9, 1011.9, 1012.9, 1013.9],
492 [1003.2, 1004.2, 1005.2, 1006.2, 1007.2, ..., 1010.2, 1011.2, 1012.2, 1013.2, 1014.2],
493 [1002.6, 1003.6, 1004.6, 1005.6, 1006.6, ..., 1009.6, 1010.6, 1011.6, 1012.6, 1013.6],
494 [1001.7, 1002.7, 1003.7, 1004.7, 1005.7, ..., 1008.7, 1009.7, 1010.7, 1011.7, 1012.7]],
495
496 [[1002.5, 1003.5, 1004.5, 1005.5, 1006.5, ..., 1009.5, 1010.5, 1011.5, 1012.5, 1013.5],
497 [1003.3, 1004.3, 1005.3, 1006.3, 1007.3, ..., 1010.3, 1011.3, 1012.3, 1013.3, 1014.3],
498 [1003.4, 1004.4, 1005.4, 1006.4, 1007.4, ..., 1010.4, 1011.4, 1012.4, 1013.4, 1014.4],
499 [1002.6, 1003.6, 1004.6, 1005.6, 1006.6, ..., 1009.6, 1010.6, 1011.6, 1012.6, 1013.6],
500 [1001.7, 1002.7, 1003.7, 1004.7, 1005.7, ..., 1008.7, 1009.7, 1010.7, 1011.7, 1012.7],
501 [1001.5, 1002.5, 1003.5, 1004.5, 1005.5, ..., 1008.5, 1009.5, 1010.5, 1011.5, 1012.5],
502 [1002.2, 1003.2, 1004.2, 1005.2, 1006.2, ..., 1009.2, 1010.2, 1011.2, 1012.2, 1013.2],
503 [1003.1, 1004.1, 1005.1, 1006.1, 1007.1, ..., 1010.1, 1011.1, 1012.1, 1013.1, 1014.1],
504 [1003.4, 1004.4, 1005.4, 1006.4, 1007.4, ..., 1010.4, 1011.4, 1012.4, 1013.4, 1014.4],
505 [1002.9, 1003.9, 1004.9, 1005.9, 1006.9, ..., 1009.9, 1010.9, 1011.9, 1012.9, 1013.9],
506 [1001.9, 1002.9, 1003.9, 1004.9, 1005.9, ..., 1008.9, 1009.9, 1010.9, 1011.9, 1012.9]]]";
507 assert_str_eq(expected, &actual);
508 }
509
510 #[test]
511 fn dim_4_overflow_outer()
512 {
513 let a = Array4::from_shape_fn((10, 10, 3, 3), |(i, j, k, l)| i + j + k + l);
514 let actual = format!("{:2}", a);
515 let expected = "\
520[[[[ 0, 1, 2],
521 [ 1, 2, 3],
522 [ 2, 3, 4]],
523
524 [[ 1, 2, 3],
525 [ 2, 3, 4],
526 [ 3, 4, 5]],
527
528 [[ 2, 3, 4],
529 [ 3, 4, 5],
530 [ 4, 5, 6]],
531
532 ...,
533
534 [[ 7, 8, 9],
535 [ 8, 9, 10],
536 [ 9, 10, 11]],
537
538 [[ 8, 9, 10],
539 [ 9, 10, 11],
540 [10, 11, 12]],
541
542 [[ 9, 10, 11],
543 [10, 11, 12],
544 [11, 12, 13]]],
545
546
547 [[[ 1, 2, 3],
548 [ 2, 3, 4],
549 [ 3, 4, 5]],
550
551 [[ 2, 3, 4],
552 [ 3, 4, 5],
553 [ 4, 5, 6]],
554
555 [[ 3, 4, 5],
556 [ 4, 5, 6],
557 [ 5, 6, 7]],
558
559 ...,
560
561 [[ 8, 9, 10],
562 [ 9, 10, 11],
563 [10, 11, 12]],
564
565 [[ 9, 10, 11],
566 [10, 11, 12],
567 [11, 12, 13]],
568
569 [[10, 11, 12],
570 [11, 12, 13],
571 [12, 13, 14]]],
572
573
574 [[[ 2, 3, 4],
575 [ 3, 4, 5],
576 [ 4, 5, 6]],
577
578 [[ 3, 4, 5],
579 [ 4, 5, 6],
580 [ 5, 6, 7]],
581
582 [[ 4, 5, 6],
583 [ 5, 6, 7],
584 [ 6, 7, 8]],
585
586 ...,
587
588 [[ 9, 10, 11],
589 [10, 11, 12],
590 [11, 12, 13]],
591
592 [[10, 11, 12],
593 [11, 12, 13],
594 [12, 13, 14]],
595
596 [[11, 12, 13],
597 [12, 13, 14],
598 [13, 14, 15]]],
599
600
601 ...,
602
603
604 [[[ 7, 8, 9],
605 [ 8, 9, 10],
606 [ 9, 10, 11]],
607
608 [[ 8, 9, 10],
609 [ 9, 10, 11],
610 [10, 11, 12]],
611
612 [[ 9, 10, 11],
613 [10, 11, 12],
614 [11, 12, 13]],
615
616 ...,
617
618 [[14, 15, 16],
619 [15, 16, 17],
620 [16, 17, 18]],
621
622 [[15, 16, 17],
623 [16, 17, 18],
624 [17, 18, 19]],
625
626 [[16, 17, 18],
627 [17, 18, 19],
628 [18, 19, 20]]],
629
630
631 [[[ 8, 9, 10],
632 [ 9, 10, 11],
633 [10, 11, 12]],
634
635 [[ 9, 10, 11],
636 [10, 11, 12],
637 [11, 12, 13]],
638
639 [[10, 11, 12],
640 [11, 12, 13],
641 [12, 13, 14]],
642
643 ...,
644
645 [[15, 16, 17],
646 [16, 17, 18],
647 [17, 18, 19]],
648
649 [[16, 17, 18],
650 [17, 18, 19],
651 [18, 19, 20]],
652
653 [[17, 18, 19],
654 [18, 19, 20],
655 [19, 20, 21]]],
656
657
658 [[[ 9, 10, 11],
659 [10, 11, 12],
660 [11, 12, 13]],
661
662 [[10, 11, 12],
663 [11, 12, 13],
664 [12, 13, 14]],
665
666 [[11, 12, 13],
667 [12, 13, 14],
668 [13, 14, 15]],
669
670 ...,
671
672 [[16, 17, 18],
673 [17, 18, 19],
674 [18, 19, 20]],
675
676 [[17, 18, 19],
677 [18, 19, 20],
678 [19, 20, 21]],
679
680 [[18, 19, 20],
681 [19, 20, 21],
682 [20, 21, 22]]]]";
683 assert_str_eq(expected, &actual);
684 }
685}