terble 0.1.0

Simple CLI table generator
Documentation
use std::vec;

pub struct Table {
    pub headers: Vec<String>,
    pub rows: Vec<Vec<String>>,
    size: usize,
    sizes: Vec<usize>,
}

impl Table {
    pub fn new(headers: Vec<String>, rows: Vec<Vec<String>>) -> Self {
        let mut content = vec![headers];
        for row in rows {
            content.push(row)
        }

        let mut max_len = content[0].len();
        for i in 0..content.len() {
            let len = content[i].len();
            if len > max_len {
                max_len = len;
            }
        }

        for i in 0..content.len() {
            let len = content[i].len();
            if len != max_len {
                for _ in 0..max_len - len {
                    content[i].push(String::from("<None>"));
                }
            }
        }

        let new_headers = &content[0];
        let new_rows = &content[1..];
        let (x, _) = termion::terminal_size().unwrap();

        // let sizes = Self::get_sizes(content.clone());

        let mut s = Self {
            headers: new_headers.to_vec(),
            rows: new_rows.to_vec(),
            size: x as usize,
            sizes: vec![0; new_headers.to_vec().len()],
        };

        s.set_sizes();

        s
    }

    pub fn draw(&self) {
        self.draw_header();
        self.draw_rows();
    }

    fn draw_horizontal(&self) {
        let border = "-".repeat(self.size as usize);
        println!("{}", border)
    }

    fn set_sizes(&mut self) {
        let headers = &self.headers;
        let rows = &self.rows;

        let mut content = vec![headers];
        for row in rows {
            content.push(row)
        }

        let mut max_lens = vec![0; content[0].len()];
        for i in 0..content.len() {
            for j in 0..content[i].len() {
                let mut len = content[i][j].len() + 3;
                if j == 0 {
                    len += 1;
                }
                if max_lens[j] < len {
                    max_lens[j] = len;
                }
            }
        }

        let mut summaric_len: usize;
        let mut i = 0;
        loop {
            let value = max_lens[i];

            let mut max = max_lens[0];
            for i in 0..max_lens.len() {
                if max_lens[i] > max {
                    max = max_lens[i];
                }
            }
            if value != 3 && max == value {
                max_lens[i] = max_lens[i] - 1;
            }

            i = (i + 1) % max_lens.len();

            summaric_len = max_lens.iter().sum();

            if summaric_len <= self.size {
                break;
            }
        }

        self.sizes = max_lens;
        self.size = summaric_len;
    }

    fn draw_header(&self) {
        self.draw_horizontal();

        let headers = self.headers.to_vec();
        let sizes = self.sizes.to_vec();
        // let border_count = headers.len() + 1;
        for i in 0..headers.len() {
            let has_right = if i == 0 { 1 } else { 0 };
            // let mut cell_string = if i == 0 { "*" } else { "" };
            let total_space = sizes[i];
            let whitespace_len = total_space - (headers[i].len() + has_right + 1);
            // print!("{}", whitespace_len);
            let whitespace_left_len = (whitespace_len as f32 / 2_f32).floor() as usize;
            let whitespace_right_len = whitespace_len - whitespace_left_len;
            let whitespace_left = " ".repeat(whitespace_left_len);
            let whitespace_right = " ".repeat(whitespace_right_len);
            let cell_string = format!(
                "{}{}{}{}|",
                if has_right == 1 { "|" } else { "" },
                whitespace_left,
                headers[i],
                whitespace_right
            );
            // let cell_string = ASCII_LOWER[i].to_string().repeat(sizes[i] as usize);
            print!("{}", cell_string);
            if i == headers.len() - 1 {
                println!();
            }
        }
        self.draw_horizontal();
    }
    fn draw_rows(&self) {
        let headers = self.rows.to_vec();
        let sizes = self.sizes.to_vec();

        for j in 0..headers.len() {
            // let border_count = headers.len() + 1;
            for i in 0..headers[j].len() {
                let has_right = if i == 0 { 1 } else { 0 };
                // let mut cell_string = if i == 0 { "*" } else { "" };
                // let total_space = sizes[i];
                let max_space = if headers[j][i].len() > sizes[i] {
                    sizes[i] - 3
                } else {
                    headers[j][i].len()
                };

                let cell_string = &format!(
                    "{} {}",
                    if has_right == 1 { "|" } else { "" },
                    &headers[j][i][..max_space],
                    // whitespace_right,
                );
                let cs;
                if sizes[i] > cell_string.len() + 2 {
                    let whitespace_right_len = sizes[i] - (cell_string.len() + 1);
                    let whitespace_right = " ".repeat(whitespace_right_len);
                    cs = format!("{}{}|", cell_string, whitespace_right);
                } else {
                    cs = format!("{} |", cell_string);
                }
                print!("{}", cs);
                if i == headers.len() - 1 {}
            }
            println!();
            if j != headers.len() - 1 {
                self.draw_horizontal();
            }
        }
        self.draw_horizontal();
    }
}