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 struct Array {
10 colors: Vec<Color>,
11 size: usize,
12}
13
14impl Array {
15 pub fn new(code: QrCode) -> MyResult<Array> {
16 let colors = code.to_colors();
17 let size = colors.len() as f64;
18 let size = size.sqrt().approx_as_by::<usize, RoundToNearest>()?;
19 let array = Array { colors, size };
20 Ok(array)
21 }
22
23 pub fn print(&self) {
24 println!();
25 for row in (0..self.size).step_by(2) {
26 print!(" ");
27 for col in 0..self.size {
28 let upper = self.get_color(row, col);
29 let lower = self.get_color(row + 1, col);
30 match (upper, lower) {
31 (Color::Light, Color::Light) => print!(" "),
32 (Color::Light, Color::Dark) => print!("{}", LOWER_BLOCK),
33 (Color::Dark, Color::Light) => print!("{}", UPPER_BLOCK),
34 (Color::Dark, Color::Dark) => print!("{}", FULL_BLOCK),
35 }
36 }
37 println!();
38 }
39 println!();
40 }
41
42 fn get_color(&self, row: usize, col: usize) -> Color {
43 let index = (row * self.size) + col;
44 if index < self.colors.len() { self.colors[index] } else { Color::Light }
45 }
46}