@@ -11,9 +11,197 @@ use super::{
11
11
Data ,
12
12
Dimension ,
13
13
NdProducer ,
14
+ Ix
14
15
} ;
15
16
use crate :: dimension:: IntoDimension ;
16
17
18
+ #[ derive( Debug ) ]
19
+ enum ArrayDisplayMode {
20
+ // Array is small enough to me printed without omitting any values.
21
+ Full ,
22
+ // Omit central values of the nth axis. Since we print that axis horizontally, ellipses
23
+ // on each row do something like a split of the array into 2 parts vertically.
24
+ VSplit ,
25
+ // Omit central values of the certain axis. Since we do it only once, ellipses on each row
26
+ // do something like a split of the array into 2 parts horizontally.
27
+ HSplit ( Ix ) ,
28
+ // Both `VSplit` and `HSplit` hold.
29
+ DoubleSplit ( Ix ) ,
30
+ }
31
+
32
+ const PRINT_ELEMENTS_LIMIT : Ix = 5 ;
33
+
34
+ impl ArrayDisplayMode {
35
+ fn from_array < A , S , D > ( arr : & ArrayBase < S , D > , limit : usize ) -> ArrayDisplayMode
36
+ where S : Data < Elem =A > ,
37
+ D : Dimension
38
+ {
39
+ let last_dim = arr. shape ( ) . len ( ) - 1 ;
40
+
41
+ let mut overflow_axis_pair: ( Option < usize > , Option < usize > ) = ( None , None ) ;
42
+ for ( axis, axis_size) in arr. shape ( ) . iter ( ) . enumerate ( ) . rev ( ) {
43
+ if * axis_size >= 2 * limit + 1 {
44
+ match overflow_axis_pair. 0 {
45
+ Some ( _) => {
46
+ if let None = overflow_axis_pair. 1 {
47
+ overflow_axis_pair. 1 = Some ( axis) ;
48
+ }
49
+ } ,
50
+ None => {
51
+ if axis != last_dim {
52
+ return ArrayDisplayMode :: HSplit ( axis) ;
53
+ }
54
+ overflow_axis_pair. 0 = Some ( axis) ;
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ match overflow_axis_pair {
61
+ ( Some ( _) , Some ( h_axis) ) => ArrayDisplayMode :: DoubleSplit ( h_axis) ,
62
+ ( Some ( _) , None ) => ArrayDisplayMode :: VSplit ,
63
+ ( None , _) => ArrayDisplayMode :: Full ,
64
+ }
65
+ }
66
+
67
+ fn h_split_offset ( & self ) -> Option < Ix > {
68
+ match self {
69
+ ArrayDisplayMode :: DoubleSplit ( axis) | ArrayDisplayMode :: HSplit ( axis) => {
70
+ Some ( axis + 1usize )
71
+ } ,
72
+ _ => None
73
+ }
74
+ }
75
+ }
76
+
77
+ fn format_array_v2 < A , S , D , F > ( view : & ArrayBase < S , D > ,
78
+ f : & mut fmt:: Formatter ,
79
+ mut format : F ,
80
+ limit : usize ) -> fmt:: Result
81
+ where F : FnMut ( & A , & mut fmt:: Formatter ) -> fmt:: Result ,
82
+ D : Dimension ,
83
+ S : Data < Elem =A > ,
84
+ {
85
+ let display_mode = ArrayDisplayMode :: from_array ( view, limit) ;
86
+
87
+ let ndim = view. dim ( ) . into_dimension ( ) . slice ( ) . len ( ) ;
88
+ let nth_idx_max = view. shape ( ) . iter ( ) . last ( ) . unwrap ( ) ;
89
+
90
+ // None will be an empty iter.
91
+ let mut last_index = match view. dim ( ) . into_dimension ( ) . first_index ( ) {
92
+ None => view. dim ( ) . into_dimension ( ) . clone ( ) ,
93
+ Some ( ix) => ix,
94
+ } ;
95
+ for _ in 0 ..ndim {
96
+ write ! ( f, "[" ) ?;
97
+ }
98
+ let mut first = true ;
99
+ // Shows if ellipses for vertical split were printed.
100
+ let mut printed_ellipses_v = false ;
101
+ // Shows if ellipses for horizontal split were printed.
102
+ let mut printed_ellipses_h = false ;
103
+ // Shows if the row was printed for the first time after horizontal split.
104
+ let mut no_rows_after_skip_yet = false ;
105
+
106
+ // Simply use the indexed iterator, and take the index wraparounds
107
+ // as cues for when to add []'s and how many to add.
108
+ for ( index, elt) in view. indexed_iter ( ) {
109
+ let index = index. into_dimension ( ) ;
110
+ let take_n = if ndim == 0 { 1 } else { ndim - 1 } ;
111
+ let mut update_index = false ;
112
+
113
+ let mut print_row = true ;
114
+ match display_mode {
115
+ ArrayDisplayMode :: HSplit ( axis) | ArrayDisplayMode :: DoubleSplit ( axis) => {
116
+ let sa_idx_max = view. shape ( ) . iter ( ) . skip ( axis) . next ( ) . unwrap ( ) ;
117
+ let sa_idx_val = index. slice ( ) . iter ( ) . skip ( axis) . next ( ) . unwrap ( ) ;
118
+ if sa_idx_val >= & limit && sa_idx_val < & ( sa_idx_max - & limit) {
119
+ print_row = false ;
120
+ no_rows_after_skip_yet = true ;
121
+ }
122
+ } ,
123
+ _ => { }
124
+ }
125
+
126
+ for ( i, ( a, b) ) in index. slice ( )
127
+ . iter ( )
128
+ . take ( take_n)
129
+ . zip ( last_index. slice ( ) . iter ( ) )
130
+ . enumerate ( ) {
131
+ if a != b {
132
+ if print_row {
133
+ printed_ellipses_v = false ;
134
+ // New row.
135
+ // # of ['s needed
136
+ let n = ndim - i - 1 ;
137
+ if !no_rows_after_skip_yet {
138
+ for _ in 0 ..n {
139
+ write ! ( f, "]" ) ?;
140
+ }
141
+ write ! ( f, "," ) ?;
142
+ write ! ( f, "\n " ) ?;
143
+ }
144
+ no_rows_after_skip_yet = false ;
145
+ for _ in 0 ..ndim - n {
146
+ write ! ( f, " " ) ?;
147
+ }
148
+ for _ in 0 ..n {
149
+ write ! ( f, "[" ) ?;
150
+ }
151
+ } else if !printed_ellipses_h {
152
+ let n = ndim - i - 1 ;
153
+ for _ in 0 ..n {
154
+ write ! ( f, "]" ) ?;
155
+ }
156
+ write ! ( f, "," ) ?;
157
+ write ! ( f, "\n " ) ?;
158
+ for _ in 0 ..display_mode. h_split_offset ( ) . unwrap ( ) {
159
+ write ! ( f, " " ) ?;
160
+ }
161
+ write ! ( f, "...,\n " ) ?;
162
+ printed_ellipses_h = true ;
163
+ }
164
+ first = true ;
165
+ update_index = true ;
166
+ break ;
167
+ }
168
+ }
169
+
170
+ if print_row {
171
+ let mut print_elt = true ;
172
+ let nth_idx_val = index. slice ( ) . iter ( ) . last ( ) . unwrap ( ) ;
173
+ match display_mode {
174
+ ArrayDisplayMode :: VSplit | ArrayDisplayMode :: DoubleSplit ( _) => {
175
+ if nth_idx_val >= & limit && nth_idx_val < & ( nth_idx_max - & limit) {
176
+ print_elt = false ;
177
+ if !printed_ellipses_v {
178
+ write ! ( f, ", ..." ) ?;
179
+ printed_ellipses_v = true ;
180
+ }
181
+ }
182
+ }
183
+ _ => { }
184
+ }
185
+
186
+ if print_elt {
187
+ if !first {
188
+ write ! ( f, ", " ) ?;
189
+ }
190
+ first = false ;
191
+ format ( elt, f) ?;
192
+ }
193
+ }
194
+
195
+ if update_index {
196
+ last_index = index;
197
+ }
198
+ }
199
+ for _ in 0 ..ndim {
200
+ write ! ( f, "]" ) ?;
201
+ }
202
+ Ok ( ( ) )
203
+ }
204
+
17
205
fn format_array < A , S , D , F > ( view : & ArrayBase < S , D > , f : & mut fmt:: Formatter ,
18
206
mut format : F )
19
207
-> fmt:: Result
@@ -92,7 +280,7 @@ impl<'a, A: fmt::Display, S, D: Dimension> fmt::Display for ArrayBase<S, D>
92
280
where S : Data < Elem =A > ,
93
281
{
94
282
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
95
- format_array ( self , f, <_ >:: fmt)
283
+ format_array_v2 ( self , f, <_ >:: fmt, PRINT_ELEMENTS_LIMIT )
96
284
}
97
285
}
98
286
@@ -105,7 +293,7 @@ impl<'a, A: fmt::Debug, S, D: Dimension> fmt::Debug for ArrayBase<S, D>
105
293
{
106
294
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
107
295
// Add extra information for Debug
108
- format_array ( self , f, <_ >:: fmt) ?;
296
+ format_array_v2 ( self , f, <_ >:: fmt, PRINT_ELEMENTS_LIMIT ) ?;
109
297
write ! ( f, " shape={:?}, strides={:?}, layout={:?}" ,
110
298
self . shape( ) , self . strides( ) , layout=self . view( ) . layout( ) ) ?;
111
299
match D :: NDIM {
0 commit comments