tabled/grid/dimension/
complete_dimension.rs

1use crate::grid::{
2    config::{ColoredConfig, Entity, SpannedConfig},
3    dimension::{Dimension, Estimate, PeekableGridDimension},
4    records::{vec_records::Cell, IntoRecords, Records},
5};
6
7/// CompleteDimension is a [`Dimension`] implementation for a [`Table`]
8///
9/// [`Table`]: crate::Table
10#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Clone)]
11// todo; change to vec ....
12pub struct CompleteDimension {
13    width: Option<Vec<usize>>,
14    height: Option<Vec<usize>>,
15}
16
17impl CompleteDimension {
18    /// Checks whether is the dimensions is set.
19    pub fn is_complete(&self) -> bool {
20        self.width.is_some() && self.height.is_some()
21    }
22
23    /// Checks whether is nothing was set.
24    pub fn is_empty(&self) -> bool {
25        self.width.is_none() && self.height.is_none()
26    }
27
28    /// Set column widths.
29    ///
30    /// In general the method is only considered to be useful to a [`TableOption`].
31    ///
32    /// BE CAREFUL WITH THIS METHOD as it supposed that the content is not bigger than the provided widths.
33    ///
34    /// [`TableOption`]: crate::settings::TableOption
35    pub fn set_widths(&mut self, columns: Vec<usize>) {
36        self.width = Some(columns);
37    }
38
39    /// Set rows heights.
40    ///
41    /// In general the method is only considered to be useful to a [`TableOption`].
42    ///
43    /// BE CAREFUL WITH THIS METHOD as it supposed that the content is not bigger than the provided heights.
44    ///
45    /// [`TableOption`]: crate::settings::TableOption
46    pub fn set_heights(&mut self, rows: Vec<usize>) {
47        self.height = Some(rows);
48    }
49
50    /// Force width estimation.
51    pub fn clear_width(&mut self) {
52        self.width = None;
53    }
54
55    /// Force height estimation.
56    pub fn clear_height(&mut self) {
57        self.height = None;
58    }
59
60    /// Force width and height estimation.
61    pub fn clear(&mut self) {
62        self.width = None;
63        self.height = None;
64    }
65
66    /// Copies a reference from self.
67    pub fn reastimate(&mut self, hint: Option<Entity>) {
68        dims_reastimate_likely(self, hint);
69    }
70
71    /// Return inner width list.
72    pub fn get_widths(&self) -> Option<&[usize]> {
73        self.width.as_deref()
74    }
75
76    /// Return inner heights list.
77    pub fn get_heights(&self) -> Option<&[usize]> {
78        self.height.as_deref()
79    }
80}
81
82impl Dimension for CompleteDimension {
83    fn get_width(&self, column: usize) -> usize {
84        let width = self
85            .width
86            .as_ref()
87            .expect("It must always be Some at this point");
88
89        width[column]
90    }
91
92    fn get_height(&self, row: usize) -> usize {
93        let height = self
94            .height
95            .as_ref()
96            .expect("It must always be Some at this point");
97
98        height[row]
99    }
100}
101
102impl<R> Estimate<R, SpannedConfig> for CompleteDimension
103where
104    R: Records,
105    <R::Iter as IntoRecords>::Cell: Cell,
106{
107    fn estimate(&mut self, records: R, cfg: &SpannedConfig) {
108        match (self.width.is_some(), self.height.is_some()) {
109            (true, true) => {}
110            (true, false) => {
111                self.height = Some(PeekableGridDimension::height(records, cfg));
112            }
113            (false, true) => {
114                self.width = Some(PeekableGridDimension::width(records, cfg));
115            }
116            (false, false) => {
117                let (width, height) = PeekableGridDimension::dimension(records, cfg);
118
119                self.width = Some(width);
120                self.height = Some(height);
121            }
122        }
123    }
124}
125
126impl<R> Estimate<R, ColoredConfig> for CompleteDimension
127where
128    R: Records,
129    <R::Iter as IntoRecords>::Cell: Cell,
130{
131    fn estimate(&mut self, records: R, cfg: &ColoredConfig) {
132        Estimate::estimate(self, records, cfg.as_ref())
133    }
134}
135
136fn dims_reastimate_likely(dims: &mut CompleteDimension, hint: Option<Entity>) {
137    let hint = match hint {
138        Some(hint) => hint,
139        None => return,
140    };
141
142    match hint {
143        Entity::Global | Entity::Cell(_, _) => {
144            dims.clear_width();
145            dims.clear_height()
146        }
147        Entity::Column(_) => {
148            dims.clear_width();
149        }
150        Entity::Row(_) => dims.clear_height(),
151    }
152}