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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#![allow(dead_code)]

use crate::{options::Options, row::Row, HAlign, VAlign};

/// Builder for the [`Grid`] type.
///
/// [`Grid`]: struct.Grid.html
pub struct GridBuilder {
    inner: Grid,
}

/// Data type for crating a [`Grid`].
///
/// [`Grid`]: struct.Grid.html
pub struct Grid {
    /// These options will be used if the equivalent is not provided
    /// by the underlying [`Row`] type.
    ///
    /// [`Row`]: struct.Row.html
    pub default_options: Options,

    /// Width in chars for each column of the [`Grid`].
    ///
    /// [`Grid`]: struct.Grid.html
    pub column_width: Option<usize>,

    /// Number of char spaces for each padding space between grid columns.
    pub padding_size: Option<usize>,

    /// Collection of rows that this [`Grid`] contains.
    ///
    /// [`Grid`]: struct.Grid.html
    pub rows: Vec<Row>,
}

impl Grid {
    /// Creates a [`Grid`] bye specifying its rows.
    ///
    /// [`Grid`]: struct.Grid.html
    pub fn new(rows: Vec<Row>) -> Self {
        let default_options = Options {
            col_span: None,
            h_align: None,
            v_align: None,
            blank_char: None,
        };
        let grid = Self {
            default_options,
            column_width: None,
            padding_size: None,
            rows,
        };
        grid
    }

    /// Creates a [`GridBuilder`] initiated with rows.
    ///
    /// [`GridBuilder`]: struct.GridBuilder.html
    pub fn builder(rows: Vec<Row>) -> GridBuilder {
        GridBuilder {
            inner: Grid::new(rows),
        }
    }

    /// Format the grid into a string.
    fn render(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        for row in &self.rows {
            row.render(
                f,
                &self.default_options,
                self.column_width,
                self.padding_size,
            )?;
        }
        Ok(())
    }
}

impl std::fmt::Display for Grid {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        self.render(f)
    }
}

impl GridBuilder {
    /// Builds a [`Grid`] from a [`GridBuilder`].
    ///
    /// [`GridBuilder`]: struct.GridBuilder.html
    /// [`Grid`]: struct.Grid.html
    pub fn build(self) -> Grid {
        self.inner
    }

    /// Sets the default column span for all the cells of the grid. If a cell specifies
    /// a column span it will be used instead of the grids default value.
    pub fn default_colspan(mut self, default_colspan: usize) -> Self {
        if default_colspan == 0 {
            panic!("Column span cannot be 0!");
        }
        self.inner.default_options.col_span = Some(default_colspan);
        self
    }

    /// Sets the default horizontal alignment for all the cells of the grid. If a cell specifies
    /// a horizontal alignment it will be used instead of the grids default value.
    pub fn default_h_align(mut self, default_h_align: HAlign) -> Self {
        self.inner.default_options.h_align = Some(default_h_align);
        self
    }

    /// Sets the default vertical alignment for all the cells of the grid. If a cell specifies
    /// a vertical alignment it will be used instead of the grids default value.
    pub fn default_v_align(mut self, default_v_align: VAlign) -> Self {
        self.inner.default_options.v_align = Some(default_v_align);
        self
    }

    /// Sets the default blank char for all the cells of the grid. If a cell specifies
    /// a blank char it will be used instead of the grids default value.
    pub fn default_blank_char(mut self, default_blank_char: char) -> Self {
        self.inner.default_options.blank_char = Some(default_blank_char);
        self
    }

    /// Width of each column in the grid in number of chars.
    pub fn column_width(mut self, column_width: usize) -> Self {
        self.inner.column_width = Some(column_width);
        self
    }

    /// Width of each padding space in the grid in number of chars.
    pub fn padding_size(mut self, padding_size: usize) -> Self {
        self.inner.padding_size = Some(padding_size);
        self
    }
}