Skip to main content

qrsimple_cli/
array.rs

1use crate::error::MyResult;
2use conv::{ConvUtil, RoundToNearest};
3use qrcode::{Color, QrCode};
4
5const FULL_BLOCK: char = '\u{2588}';
6const UPPER_BLOCK: char = '\u{2580}';
7const LOWER_BLOCK: char = '\u{2584}';
8
9pub static SEXTANT_BLOCKS: [char; 64] = [
10    '\u{0020}', // SPACE
11    '\u{1FB00}', // BLOCK SEXTANT-1
12    '\u{1FB01}', // BLOCK SEXTANT-2
13    '\u{1FB02}', // BLOCK SEXTANT-12
14    '\u{1FB03}', // BLOCK SEXTANT-3
15    '\u{1FB04}', // BLOCK SEXTANT-13
16    '\u{1FB05}', // BLOCK SEXTANT-23
17    '\u{1FB06}', // BLOCK SEXTANT-123
18    '\u{1FB07}', // BLOCK SEXTANT-4
19    '\u{1FB08}', // BLOCK SEXTANT-14
20    '\u{1FB09}', // BLOCK SEXTANT-24
21    '\u{1FB0A}', // BLOCK SEXTANT-124
22    '\u{1FB0B}', // BLOCK SEXTANT-34
23    '\u{1FB0C}', // BLOCK SEXTANT-134
24    '\u{1FB0D}', // BLOCK SEXTANT-234
25    '\u{1FB0E}', // BLOCK SEXTANT-1234
26    '\u{1FB0F}', // BLOCK SEXTANT-5
27    '\u{1FB10}', // BLOCK SEXTANT-15
28    '\u{1FB11}', // BLOCK SEXTANT-25
29    '\u{1FB12}', // BLOCK SEXTANT-125
30    '\u{1FB13}', // BLOCK SEXTANT-35
31    '\u{258C}', // LEFT HALF BLOCK
32    '\u{1FB14}', // BLOCK SEXTANT-235
33    '\u{1FB15}', // BLOCK SEXTANT-1235
34    '\u{1FB16}', // BLOCK SEXTANT-45
35    '\u{1FB17}', // BLOCK SEXTANT-145
36    '\u{1FB18}', // BLOCK SEXTANT-245
37    '\u{1FB19}', // BLOCK SEXTANT-1245
38    '\u{1FB1A}', // BLOCK SEXTANT-345
39    '\u{1FB1B}', // BLOCK SEXTANT-1345
40    '\u{1FB1C}', // BLOCK SEXTANT-2345
41    '\u{1FB1D}', // BLOCK SEXTANT-12345
42    '\u{1FB1E}', // BLOCK SEXTANT-6
43    '\u{1FB1F}', // BLOCK SEXTANT-16
44    '\u{1FB20}', // BLOCK SEXTANT-26
45    '\u{1FB21}', // BLOCK SEXTANT-126
46    '\u{1FB22}', // BLOCK SEXTANT-36
47    '\u{1FB23}', // BLOCK SEXTANT-136
48    '\u{1FB24}', // BLOCK SEXTANT-236
49    '\u{1FB25}', // BLOCK SEXTANT-1236
50    '\u{1FB26}', // BLOCK SEXTANT-46
51    '\u{1FB27}', // BLOCK SEXTANT-146
52    '\u{2590}', // RIGHT HALF BLOCK
53    '\u{1FB28}', // BLOCK SEXTANT-1246
54    '\u{1FB29}', // BLOCK SEXTANT-346
55    '\u{1FB2A}', // BLOCK SEXTANT-1346
56    '\u{1FB2B}', // BLOCK SEXTANT-2346
57    '\u{1FB2C}', // BLOCK SEXTANT-12346
58    '\u{1FB2D}', // BLOCK SEXTANT-56
59    '\u{1FB2E}', // BLOCK SEXTANT-156
60    '\u{1FB2F}', // BLOCK SEXTANT-256
61    '\u{1FB30}', // BLOCK SEXTANT-1256
62    '\u{1FB31}', // BLOCK SEXTANT-356
63    '\u{1FB32}', // BLOCK SEXTANT-1356
64    '\u{1FB33}', // BLOCK SEXTANT-2356
65    '\u{1FB34}', // BLOCK SEXTANT-12356
66    '\u{1FB35}', // BLOCK SEXTANT-456
67    '\u{1FB36}', // BLOCK SEXTANT-1456
68    '\u{1FB37}', // BLOCK SEXTANT-2456
69    '\u{1FB38}', // BLOCK SEXTANT-12456
70    '\u{1FB39}', // BLOCK SEXTANT-3456
71    '\u{1FB3A}', // BLOCK SEXTANT-13456
72    '\u{1FB3B}', // BLOCK SEXTANT-23456
73    '\u{2588}', // FULL BLOCK
74];
75
76pub static OCTANT_BLOCKS: [char; 256] = [
77    '\u{0020}', // SPACE
78    '\u{1CEA8}', // LEFT HALF UPPER ONE QUARTER BLOCK
79    '\u{1CEAB}', // RIGHT HALF UPPER ONE QUARTER BLOCK
80    '\u{1FB82}', // UPPER ONE QUARTER BLOCK
81    '\u{1CD00}', // BLOCK OCTANT-3
82    '\u{2598}', // QUADRANT UPPER LEFT
83    '\u{1CD01}', // BLOCK OCTANT-23
84    '\u{1CD02}', // BLOCK OCTANT-123
85    '\u{1CD03}', // BLOCK OCTANT-4
86    '\u{1CD04}', // BLOCK OCTANT-14
87    '\u{259D}', // QUADRANT UPPER RIGHT
88    '\u{1CD05}', // BLOCK OCTANT-124
89    '\u{1CD06}', // BLOCK OCTANT-34
90    '\u{1CD07}', // BLOCK OCTANT-134
91    '\u{1CD08}', // BLOCK OCTANT-234
92    '\u{2580}', // UPPER HALF BLOCK
93    '\u{1CD09}', // BLOCK OCTANT-5
94    '\u{1CD0A}', // BLOCK OCTANT-15
95    '\u{1CD0B}', // BLOCK OCTANT-25
96    '\u{1CD0C}', // BLOCK OCTANT-125
97    '\u{1FBE6}', // MIDDLE LEFT ONE QUARTER BLOCK
98    '\u{1CD0D}', // BLOCK OCTANT-135
99    '\u{1CD0E}', // BLOCK OCTANT-235
100    '\u{1CD0F}', // BLOCK OCTANT-1235
101    '\u{1CD10}', // BLOCK OCTANT-45
102    '\u{1CD11}', // BLOCK OCTANT-145
103    '\u{1CD12}', // BLOCK OCTANT-245
104    '\u{1CD13}', // BLOCK OCTANT-1245
105    '\u{1CD14}', // BLOCK OCTANT-345
106    '\u{1CD15}', // BLOCK OCTANT-1345
107    '\u{1CD16}', // BLOCK OCTANT-2345
108    '\u{1CD17}', // BLOCK OCTANT-12345
109    '\u{1CD18}', // BLOCK OCTANT-6
110    '\u{1CD19}', // BLOCK OCTANT-16
111    '\u{1CD1A}', // BLOCK OCTANT-26
112    '\u{1CD1B}', // BLOCK OCTANT-126
113    '\u{1CD1C}', // BLOCK OCTANT-36
114    '\u{1CD1D}', // BLOCK OCTANT-136
115    '\u{1CD1E}', // BLOCK OCTANT-236
116    '\u{1CD1F}', // BLOCK OCTANT-1236
117    '\u{1FBE7}', // MIDDLE RIGHT ONE QUARTER BLOCK
118    '\u{1CD20}', // BLOCK OCTANT-146
119    '\u{1CD21}', // BLOCK OCTANT-246
120    '\u{1CD22}', // BLOCK OCTANT-1246
121    '\u{1CD23}', // BLOCK OCTANT-346
122    '\u{1CD24}', // BLOCK OCTANT-1346
123    '\u{1CD25}', // BLOCK OCTANT-2346
124    '\u{1CD26}', // BLOCK OCTANT-12346
125    '\u{1CD27}', // BLOCK OCTANT-56
126    '\u{1CD28}', // BLOCK OCTANT-156
127    '\u{1CD29}', // BLOCK OCTANT-256
128    '\u{1CD2A}', // BLOCK OCTANT-1256
129    '\u{1CD2B}', // BLOCK OCTANT-356
130    '\u{1CD2C}', // BLOCK OCTANT-1356
131    '\u{1CD2D}', // BLOCK OCTANT-2356
132    '\u{1CD2E}', // BLOCK OCTANT-12356
133    '\u{1CD2F}', // BLOCK OCTANT-456
134    '\u{1CD30}', // BLOCK OCTANT-1456
135    '\u{1CD31}', // BLOCK OCTANT-2456
136    '\u{1CD32}', // BLOCK OCTANT-12456
137    '\u{1CD33}', // BLOCK OCTANT-3456
138    '\u{1CD34}', // BLOCK OCTANT-13456
139    '\u{1CD35}', // BLOCK OCTANT-23456
140    '\u{1FB85}', // UPPER THREE QUARTERS BLOCK
141    '\u{1CEA3}', // LEFT HALF LOWER ONE QUARTER BLOCK
142    '\u{1CD36}', // BLOCK OCTANT-17
143    '\u{1CD37}', // BLOCK OCTANT-27
144    '\u{1CD38}', // BLOCK OCTANT-127
145    '\u{1CD39}', // BLOCK OCTANT-37
146    '\u{1CD3A}', // BLOCK OCTANT-137
147    '\u{1CD3B}', // BLOCK OCTANT-237
148    '\u{1CD3C}', // BLOCK OCTANT-1237
149    '\u{1CD3D}', // BLOCK OCTANT-47
150    '\u{1CD3E}', // BLOCK OCTANT-147
151    '\u{1CD3F}', // BLOCK OCTANT-247
152    '\u{1CD40}', // BLOCK OCTANT-1247
153    '\u{1CD41}', // BLOCK OCTANT-347
154    '\u{1CD42}', // BLOCK OCTANT-1347
155    '\u{1CD43}', // BLOCK OCTANT-2347
156    '\u{1CD44}', // BLOCK OCTANT-12347
157    '\u{2596}', // QUADRANT LOWER LEFT
158    '\u{1CD45}', // BLOCK OCTANT-157
159    '\u{1CD46}', // BLOCK OCTANT-257
160    '\u{1CD47}', // BLOCK OCTANT-1257
161    '\u{1CD48}', // BLOCK OCTANT-357
162    '\u{258C}', // LEFT HALF BLOCK
163    '\u{1CD49}', // BLOCK OCTANT-2357
164    '\u{1CD4A}', // BLOCK OCTANT-12357
165    '\u{1CD4B}', // BLOCK OCTANT-457
166    '\u{1CD4C}', // BLOCK OCTANT-1457
167    '\u{259E}', // QUADRANT UPPER RIGHT AND LOWER LEFT
168    '\u{1CD4D}', // BLOCK OCTANT-12457
169    '\u{1CD4E}', // BLOCK OCTANT-3457
170    '\u{1CD4F}', // BLOCK OCTANT-13457
171    '\u{1CD50}', // BLOCK OCTANT-23457
172    '\u{259B}', // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
173    '\u{1CD51}', // BLOCK OCTANT-67
174    '\u{1CD52}', // BLOCK OCTANT-167
175    '\u{1CD53}', // BLOCK OCTANT-267
176    '\u{1CD54}', // BLOCK OCTANT-1267
177    '\u{1CD55}', // BLOCK OCTANT-367
178    '\u{1CD56}', // BLOCK OCTANT-1367
179    '\u{1CD57}', // BLOCK OCTANT-2367
180    '\u{1CD58}', // BLOCK OCTANT-12367
181    '\u{1CD59}', // BLOCK OCTANT-467
182    '\u{1CD5A}', // BLOCK OCTANT-1467
183    '\u{1CD5B}', // BLOCK OCTANT-2467
184    '\u{1CD5C}', // BLOCK OCTANT-12467
185    '\u{1CD5D}', // BLOCK OCTANT-3467
186    '\u{1CD5E}', // BLOCK OCTANT-13467
187    '\u{1CD5F}', // BLOCK OCTANT-23467
188    '\u{1CD60}', // BLOCK OCTANT-123467
189    '\u{1CD61}', // BLOCK OCTANT-567
190    '\u{1CD62}', // BLOCK OCTANT-1567
191    '\u{1CD63}', // BLOCK OCTANT-2567
192    '\u{1CD64}', // BLOCK OCTANT-12567
193    '\u{1CD65}', // BLOCK OCTANT-3567
194    '\u{1CD66}', // BLOCK OCTANT-13567
195    '\u{1CD67}', // BLOCK OCTANT-23567
196    '\u{1CD68}', // BLOCK OCTANT-123567
197    '\u{1CD69}', // BLOCK OCTANT-4567
198    '\u{1CD6A}', // BLOCK OCTANT-14567
199    '\u{1CD6B}', // BLOCK OCTANT-24567
200    '\u{1CD6C}', // BLOCK OCTANT-124567
201    '\u{1CD6D}', // BLOCK OCTANT-34567
202    '\u{1CD6E}', // BLOCK OCTANT-134567
203    '\u{1CD6F}', // BLOCK OCTANT-234567
204    '\u{1CD70}', // BLOCK OCTANT-1234567
205    '\u{1CEA0}', // RIGHT HALF LOWER ONE QUARTER BLOCK
206    '\u{1CD71}', // BLOCK OCTANT-18
207    '\u{1CD72}', // BLOCK OCTANT-28
208    '\u{1CD73}', // BLOCK OCTANT-128
209    '\u{1CD74}', // BLOCK OCTANT-38
210    '\u{1CD75}', // BLOCK OCTANT-138
211    '\u{1CD76}', // BLOCK OCTANT-238
212    '\u{1CD77}', // BLOCK OCTANT-1238
213    '\u{1CD78}', // BLOCK OCTANT-48
214    '\u{1CD79}', // BLOCK OCTANT-148
215    '\u{1CD7A}', // BLOCK OCTANT-248
216    '\u{1CD7B}', // BLOCK OCTANT-1248
217    '\u{1CD7C}', // BLOCK OCTANT-348
218    '\u{1CD7D}', // BLOCK OCTANT-1348
219    '\u{1CD7E}', // BLOCK OCTANT-2348
220    '\u{1CD7F}', // BLOCK OCTANT-12348
221    '\u{1CD80}', // BLOCK OCTANT-58
222    '\u{1CD81}', // BLOCK OCTANT-158
223    '\u{1CD82}', // BLOCK OCTANT-258
224    '\u{1CD83}', // BLOCK OCTANT-1258
225    '\u{1CD84}', // BLOCK OCTANT-358
226    '\u{1CD85}', // BLOCK OCTANT-1358
227    '\u{1CD86}', // BLOCK OCTANT-2358
228    '\u{1CD87}', // BLOCK OCTANT-12358
229    '\u{1CD88}', // BLOCK OCTANT-458
230    '\u{1CD89}', // BLOCK OCTANT-1458
231    '\u{1CD8A}', // BLOCK OCTANT-2458
232    '\u{1CD8B}', // BLOCK OCTANT-12458
233    '\u{1CD8C}', // BLOCK OCTANT-3458
234    '\u{1CD8D}', // BLOCK OCTANT-13458
235    '\u{1CD8E}', // BLOCK OCTANT-23458
236    '\u{1CD8F}', // BLOCK OCTANT-123458
237    '\u{2597}', // QUADRANT LOWER RIGHT
238    '\u{1CD90}', // BLOCK OCTANT-168
239    '\u{1CD91}', // BLOCK OCTANT-268
240    '\u{1CD92}', // BLOCK OCTANT-1268
241    '\u{1CD93}', // BLOCK OCTANT-368
242    '\u{259A}', // QUADRANT UPPER LEFT AND LOWER RIGHT
243    '\u{1CD94}', // BLOCK OCTANT-2368
244    '\u{1CD95}', // BLOCK OCTANT-12368
245    '\u{1CD96}', // BLOCK OCTANT-468
246    '\u{1CD97}', // BLOCK OCTANT-1468
247    '\u{2590}', // RIGHT HALF BLOCK
248    '\u{1CD98}', // BLOCK OCTANT-12468
249    '\u{1CD99}', // BLOCK OCTANT-3468
250    '\u{1CD9A}', // BLOCK OCTANT-13468
251    '\u{1CD9B}', // BLOCK OCTANT-23468
252    '\u{259C}', // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
253    '\u{1CD9C}', // BLOCK OCTANT-568
254    '\u{1CD9D}', // BLOCK OCTANT-1568
255    '\u{1CD9E}', // BLOCK OCTANT-2568
256    '\u{1CD9F}', // BLOCK OCTANT-12568
257    '\u{1CDA0}', // BLOCK OCTANT-3568
258    '\u{1CDA1}', // BLOCK OCTANT-13568
259    '\u{1CDA2}', // BLOCK OCTANT-23568
260    '\u{1CDA3}', // BLOCK OCTANT-123568
261    '\u{1CDA4}', // BLOCK OCTANT-4568
262    '\u{1CDA5}', // BLOCK OCTANT-14568
263    '\u{1CDA6}', // BLOCK OCTANT-24568
264    '\u{1CDA7}', // BLOCK OCTANT-124568
265    '\u{1CDA8}', // BLOCK OCTANT-34568
266    '\u{1CDA9}', // BLOCK OCTANT-134568
267    '\u{1CDAA}', // BLOCK OCTANT-234568
268    '\u{1CDAB}', // BLOCK OCTANT-1234568
269    '\u{2582}', // LOWER ONE QUARTER BLOCK
270    '\u{1CDAC}', // BLOCK OCTANT-178
271    '\u{1CDAD}', // BLOCK OCTANT-278
272    '\u{1CDAE}', // BLOCK OCTANT-1278
273    '\u{1CDAF}', // BLOCK OCTANT-378
274    '\u{1CDB0}', // BLOCK OCTANT-1378
275    '\u{1CDB1}', // BLOCK OCTANT-2378
276    '\u{1CDB2}', // BLOCK OCTANT-12378
277    '\u{1CDB3}', // BLOCK OCTANT-478
278    '\u{1CDB4}', // BLOCK OCTANT-1478
279    '\u{1CDB5}', // BLOCK OCTANT-2478
280    '\u{1CDB6}', // BLOCK OCTANT-12478
281    '\u{1CDB7}', // BLOCK OCTANT-3478
282    '\u{1CDB8}', // BLOCK OCTANT-13478
283    '\u{1CDB9}', // BLOCK OCTANT-23478
284    '\u{1CDBA}', // BLOCK OCTANT-123478
285    '\u{1CDBB}', // BLOCK OCTANT-578
286    '\u{1CDBC}', // BLOCK OCTANT-1578
287    '\u{1CDBD}', // BLOCK OCTANT-2578
288    '\u{1CDBE}', // BLOCK OCTANT-12578
289    '\u{1CDBF}', // BLOCK OCTANT-3578
290    '\u{1CDC0}', // BLOCK OCTANT-13578
291    '\u{1CDC1}', // BLOCK OCTANT-23578
292    '\u{1CDC2}', // BLOCK OCTANT-123578
293    '\u{1CDC3}', // BLOCK OCTANT-4578
294    '\u{1CDC4}', // BLOCK OCTANT-14578
295    '\u{1CDC5}', // BLOCK OCTANT-24578
296    '\u{1CDC6}', // BLOCK OCTANT-124578
297    '\u{1CDC7}', // BLOCK OCTANT-34578
298    '\u{1CDC8}', // BLOCK OCTANT-134578
299    '\u{1CDC9}', // BLOCK OCTANT-234578
300    '\u{1CDCA}', // BLOCK OCTANT-1234578
301    '\u{1CDCB}', // BLOCK OCTANT-678
302    '\u{1CDCC}', // BLOCK OCTANT-1678
303    '\u{1CDCD}', // BLOCK OCTANT-2678
304    '\u{1CDCE}', // BLOCK OCTANT-12678
305    '\u{1CDCF}', // BLOCK OCTANT-3678
306    '\u{1CDD0}', // BLOCK OCTANT-13678
307    '\u{1CDD1}', // BLOCK OCTANT-23678
308    '\u{1CDD2}', // BLOCK OCTANT-123678
309    '\u{1CDD3}', // BLOCK OCTANT-4678
310    '\u{1CDD4}', // BLOCK OCTANT-14678
311    '\u{1CDD5}', // BLOCK OCTANT-24678
312    '\u{1CDD6}', // BLOCK OCTANT-124678
313    '\u{1CDD7}', // BLOCK OCTANT-34678
314    '\u{1CDD8}', // BLOCK OCTANT-134678
315    '\u{1CDD9}', // BLOCK OCTANT-234678
316    '\u{1CDDA}', // BLOCK OCTANT-1234678
317    '\u{2584}', // LOWER HALF BLOCK
318    '\u{1CDDB}', // BLOCK OCTANT-15678
319    '\u{1CDDC}', // BLOCK OCTANT-25678
320    '\u{1CDDD}', // BLOCK OCTANT-125678
321    '\u{1CDDE}', // BLOCK OCTANT-35678
322    '\u{2599}', // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
323    '\u{1CDDF}', // BLOCK OCTANT-235678
324    '\u{1CDE0}', // BLOCK OCTANT-1235678
325    '\u{1CDE1}', // BLOCK OCTANT-45678
326    '\u{1CDE2}', // BLOCK OCTANT-145678
327    '\u{259F}', // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
328    '\u{1CDE3}', // BLOCK OCTANT-1245678
329    '\u{2586}', // LOWER THREE QUARTERS BLOCK
330    '\u{1CDE4}', // BLOCK OCTANT-1345678
331    '\u{1CDE5}', // BLOCK OCTANT-2345678
332    '\u{2588}', // FULL BLOCK
333];
334
335pub struct Array {
336    colors: Vec<Color>,
337    size: usize,
338}
339
340impl Array {
341    pub fn new(code: QrCode) -> MyResult<Array> {
342        let colors = code.to_colors();
343        let size = colors.len() as f64;
344        let size = size.sqrt().approx_as_by::<usize, RoundToNearest>()?;
345        let array = Array { colors, size };
346        Ok(array)
347    }
348
349    pub fn print_large(&self) {
350        println!();
351        for row in (0..self.size).step_by(2) {
352            print!("  ");
353            for col in 0..self.size {
354                let upper = self.get_color(row, col);
355                let lower = self.get_color(row + 1, col);
356                match (upper, lower) {
357                    (Color::Light, Color::Light) => print!(" "),
358                    (Color::Light, Color::Dark) => print!("{}", LOWER_BLOCK),
359                    (Color::Dark, Color::Light) => print!("{}", UPPER_BLOCK),
360                    (Color::Dark, Color::Dark) => print!("{}", FULL_BLOCK),
361                }
362            }
363            println!();
364        }
365        println!();
366    }
367
368    pub fn print_medium(&self) {
369        println!();
370        for row in (0..self.size).step_by(3) {
371            print!("  ");
372            for col in (0..self.size).step_by(2) {
373                let mut index = 0;
374                if self.get_color(row, col) == Color::Dark { index |= 1 << 0; }
375                if self.get_color(row, col + 1) == Color::Dark { index |= 1 << 1; }
376                if self.get_color(row + 1, col) == Color::Dark { index |= 1 << 2; }
377                if self.get_color(row + 1, col + 1) == Color::Dark { index |= 1 << 3; }
378                if self.get_color(row + 2, col) == Color::Dark { index |= 1 << 4; }
379                if self.get_color(row + 2, col + 1) == Color::Dark { index |= 1 << 5; }
380                print!("{}", SEXTANT_BLOCKS[index]);
381            }
382            println!();
383        }
384        println!();
385    }
386
387    pub fn print_small(&self) {
388        println!();
389        for row in (0..self.size).step_by(4) {
390            print!("  ");
391            for col in (0..self.size).step_by(2) {
392                let mut index = 0;
393                if self.get_color(row, col) == Color::Dark { index |= 1 << 0; }
394                if self.get_color(row, col + 1) == Color::Dark { index |= 1 << 1; }
395                if self.get_color(row + 1, col) == Color::Dark { index |= 1 << 2; }
396                if self.get_color(row + 1, col + 1) == Color::Dark { index |= 1 << 3; }
397                if self.get_color(row + 2, col) == Color::Dark { index |= 1 << 4; }
398                if self.get_color(row + 2, col + 1) == Color::Dark { index |= 1 << 5; }
399                if self.get_color(row + 3, col) == Color::Dark { index |= 1 << 6; }
400                if self.get_color(row + 3, col + 1) == Color::Dark { index |= 1 << 7; }
401                print!("{}", OCTANT_BLOCKS[index]);
402            }
403            println!();
404        }
405        println!();
406    }
407
408    fn get_color(&self, row: usize, col: usize) -> Color {
409        if row < self.size && col < self.size {
410            let index = (row * self.size) + col;
411            self.colors.get(index).copied().unwrap_or(Color::Light)
412        } else {
413            Color::Light
414        }
415    }
416}