1use std::borrow::Cow;
2
3use crate::grid::{
4 config::{ColoredConfig, SpannedConfig},
5 dimension::{Dimension, Estimate, SpannedVecRecordsDimension},
6 records::vec_records::{Cell, VecRecords},
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 CompleteDimensionVecRecords<'a> {
14 width: Option<Cow<'a, [usize]>>,
15 height: Option<Cow<'a, [usize]>>,
16}
17
18impl CompleteDimensionVecRecords<'_> {
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>) {
37 self.width = Some(Cow::Owned(columns));
38 }
39
40 /// Get column widths.
41 ///
42 /// In general the method is only considered to be useful to a [`TableOption`].
43 ///
44 /// BE CAREFUL WITH THIS METHOD as it supposed that the content is not bigger than the provided widths.
45 ///
46 /// [`TableOption`]: crate::settings::TableOption
47 pub fn get_widths(&self) -> Option<&'_ [usize]> {
48 self.width.as_deref()
49 }
50
51 /// Set rows heights.
52 ///
53 /// In general the method is only considered to be useful to a [`TableOption`].
54 ///
55 /// BE CAREFUL WITH THIS METHOD as it supposed that the content is not bigger than the provided heights.
56 ///
57 /// [`TableOption`]: crate::settings::TableOption
58 pub fn set_heights(&mut self, rows: Vec<usize>) {
59 self.height = Some(Cow::Owned(rows));
60 }
61
62 /// Get row heights.
63 ///
64 /// In general the method is only considered to be useful to a [`TableOption`].
65 ///
66 /// BE CAREFUL WITH THIS METHOD as it supposed that the content is not bigger than the provided widths.
67 ///
68 /// [`TableOption`]: crate::settings::TableOption
69 pub fn get_heights(&self) -> Option<&'_ [usize]> {
70 self.height.as_deref()
71 }
72
73 /// Force width estimation.
74 pub fn clear_width(&mut self) {
75 self.width = None;
76 }
77
78 /// Force height estimation.
79 pub fn clear_height(&mut self) {
80 self.height = None;
81 }
82
83 /// Copies a reference from self.
84 pub fn from_origin(&self) -> CompleteDimensionVecRecords<'_> {
85 let width = self.width.as_deref().map(Cow::Borrowed);
86 let height = self.height.as_deref().map(Cow::Borrowed);
87
88 CompleteDimensionVecRecords { width, height }
89 }
90
91 /// Copies a reference from self.
92 pub fn into_inner(self) -> (Option<Vec<usize>>, Option<Vec<usize>>) {
93 let width = self.width.map(|list| list.into_owned());
94 let height = self.height.map(|list| list.into_owned());
95
96 (width, height)
97 }
98}
99
100impl Dimension for CompleteDimensionVecRecords<'_> {
101 fn get_width(&self, column: usize) -> usize {
102 let width: &Cow<'_, [usize]> = self
103 .width
104 .as_ref()
105 .expect(msg:"It must always be Some at this point");
106
107 width[column]
108 }
109
110 fn get_height(&self, row: usize) -> usize {
111 let height: &Cow<'_, [usize]> = self
112 .height
113 .as_ref()
114 .expect(msg:"It must always be Some at this point");
115
116 height[row]
117 }
118}
119
120impl<T: AsRef<str> + Cell> Estimate<&VecRecords<T>, SpannedConfig>
121 for CompleteDimensionVecRecords<'_>
122{
123 fn estimate(&mut self, records: &VecRecords<T>, cfg: &SpannedConfig) {
124 match (self.width.is_some(), self.height.is_some()) {
125 (true, true) => {}
126 (true, false) => {
127 self.height = Some(Cow::Owned(SpannedVecRecordsDimension::height(records, cfg)));
128 }
129 (false, true) => {
130 self.width = Some(Cow::Owned(SpannedVecRecordsDimension::width(records, cfg)));
131 }
132 (false, false) => {
133 let mut dims: SpannedVecRecordsDimension = SpannedVecRecordsDimension::default();
134 dims.estimate(records, config:cfg);
135
136 let (width: Vec, height: Vec) = dims.get_values();
137 self.width = Some(Cow::Owned(width));
138 self.height = Some(Cow::Owned(height));
139 }
140 }
141 }
142}
143
144impl<T: AsRef<str> + Cell> Estimate<&VecRecords<T>, ColoredConfig>
145 for CompleteDimensionVecRecords<'_>
146{
147 fn estimate(&mut self, records: &VecRecords<T>, cfg: &ColoredConfig) {
148 self.estimate(records, config:cfg.as_ref())
149 }
150}
151