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