1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use crate::arrays::array::Array;
use crate::base::base_array::ArrayBase;
use crate::base::base_type::Numeric;

impl <N: Numeric> std::fmt::Display for Array<N> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        if f.alternate() {
            write!(f, "{}", build_string(self, true))
        } else {
            write!(f, "{}", build_string(self, false))
        }
    }
}

/// Display trait for numeric Array
pub trait ArrayDisplay<N: Numeric> {}

impl <N: Numeric> ArrayDisplay<N> for Array<N> {}

fn build_string<N: Numeric>(arr: &Array<N>, pretty: bool) -> String {
    if arr.is_empty() {
        return "[]".to_string();
    } else if arr.len() == 1 {
        return format!("[{}]", arr.elements[0]);
    }
    let multiply = arr.shape.iter().enumerate()
        .map(|(idx, _)| arr.shape[0..=idx].iter().product())
        .collect::<Vec<usize>>();
    let mut str = vec!["[".repeat(multiply.len())];
    arr.elements.iter().enumerate().for_each(|(idx, &elem)| {
        if idx == 0 && arr.shape[arr.ndim() - 1] != 1 {
            str.push(format!("{elem}, "));
        } else if idx == 0 {
            str.push(format!("{elem}"));
        } else {
            let separators = multiply.iter()
                .filter(|&s| idx % s == 0)
                .count();
            str.push("]".repeat(separators));
            if separators > 0 {
                str.push(", ".to_string());
                if pretty {
                    str.push("\n".to_string());
                    str.push(" ".repeat(arr.shape.len() - separators));
                }
            }
            str.push("[".repeat(separators));
            if idx % arr.shape[0] != arr.shape[0] - 1 {
                str.push(format!("{elem}, "));
            } else {
                str.push(format!("{elem}"));
            }
        }
    });
    multiply.iter().for_each(|_| str.push("]".to_string()));
    str.join("")
}