aboutsummaryrefslogtreecommitdiff
path: root/system.old/libraries/format/table.zig
blob: e26be32ca5cea1b274483cb49d6907ca768c2257 (plain)
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//! Table formatting

const io = @import("io");
const colors = @import("colors");

pub const Alignment = enum {
    left,
    right,
};

pub const Column = struct {
    name: []const u8,
    color: u32 = colors.white,
    alignment: Alignment = .left,
};

const MAX_COLUMNS = 8;
const MAX_ROWS = 256;

pub const Table = struct {
    columns: []const Column,
    col_widths: [MAX_COLUMNS]usize,
    rows: [MAX_ROWS][MAX_COLUMNS][]const u8,
    row_colors: [MAX_ROWS][MAX_COLUMNS]u32,
    row_count: usize,

    pub fn init(cols: []const Column) Table {
        var t = Table{
            .columns = cols,
            .col_widths = [_]usize{0} ** MAX_COLUMNS,
            .rows = undefined,
            .row_colors = undefined,
            .row_count = 0,
        };

        for (cols, 0..) |col, i| {
            t.col_widths[i] = col.name.len;
        }

        return t;
    }

    pub fn row(self: *Table, cells: []const []const u8) void {
        self.rowColored(cells, null);
    }

    pub fn rowColored(self: *Table, cells: []const []const u8, cell_colors: ?[]const u32) void {
        if (self.row_count >= MAX_ROWS) return;

        for (cells, 0..) |cell, i| {
            if (i >= self.columns.len) break;
            self.rows[self.row_count][i] = cell;

            if (cell_colors) |cc| {
                self.row_colors[self.row_count][i] = cc[i];
            } else {
                self.row_colors[self.row_count][i] = self.columns[i].color;
            }

            if (cell.len > self.col_widths[i]) {
                self.col_widths[i] = cell.len;
            }
        }

        self.row_count += 1;
    }

    pub fn print(self: *Table) void {
        for (self.columns, 0..) |col, i| {
            _ = io.mark(io.stream, col.name, colors.white) catch {};
            self.printPadding(self.col_widths[i] - col.name.len + 2);
        }
        _ = io.mark(io.stream, "\n", colors.white) catch {};

        for (0..self.row_count) |r| {
            for (0..self.columns.len) |c| {
                const cell = self.rows[r][c];
                const col = self.columns[c];
                const color = self.row_colors[r][c];

                if (col.alignment == .right) {
                    self.printPadding(self.col_widths[c] - cell.len);
                    _ = io.mark(io.stream, cell, color) catch {};
                    self.printPadding(2);
                } else {
                    _ = io.mark(io.stream, cell, color) catch {};
                    self.printPadding(self.col_widths[c] - cell.len + 2);
                }
            }
            _ = io.mark(io.stream, "\n", colors.white) catch {};
        }
    }

    fn printPadding(self: *Table, count: usize) void {
        _ = self;
        var i: usize = 0;
        while (i < count) : (i += 1) {
            _ = io.mark(io.stream, " ", colors.white) catch {};
        }
    }
};