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