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