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