tabled/settings/peaker/
mod.rs

1//! The module contains [`Priority`] and [`Peaker`] trait,
2//! its implementations to be used in [`Height`] and [`Width`].
3//!
4//! [`Width`]: crate::settings::width::Width
5//! [`Height`]: crate::settings::height::Height
6
7mod left;
8mod max;
9mod min;
10mod none;
11mod right;
12
13pub use left::PriorityLeft;
14pub use max::PriorityMax;
15pub use min::PriorityMin;
16pub use none::PriorityNone;
17pub use right::PriorityRight;
18
19/// A strategy of width function.
20/// It determines the order how a function is applied.
21///
22/// For example which column we shall peak to truncate when doing width alogorithms.
23pub trait Peaker {
24    /// This function returns an index which will be changed.
25    /// Or `None` if no changes are necessary.
26    ///
27    /// When [`None`] returned the alogorithm must be stopped.
28    fn peak(&mut self, mins: &[usize], values: &[usize]) -> Option<usize>;
29}
30
31/// An abstract factory to construct different [`Peaker`] methods.
32///
33/// ```
34/// use tabled::{
35///     Table,
36///     assert::assert_table,
37///     settings::{Style, peaker::Priority, Width},
38/// };
39///
40/// let data = [
41///     ("1", "Hello", 100),
42///     ("2", "World", 1000),
43/// ];
44///
45/// let mut table = Table::new(data);
46/// table.with(Style::modern());
47/// table.with(Width::wrap(15).priority(Priority::max(false)));
48///
49/// let output = table.to_string();
50///
51/// assert_table!(
52///     output,
53///     "┌───┬────┬────┐"
54///     "│ & │ &s │ i3 │"
55///     "│ s │ tr │ 2  │"
56///     "│ t │    │    │"
57///     "│ r │    │    │"
58///     "├───┼────┼────┤"
59///     "│ 1 │ He │ 10 │"
60///     "│   │ ll │ 0  │"
61///     "│   │ o  │    │"
62///     "├───┼────┼────┤"
63///     "│ 2 │ Wo │ 10 │"
64///     "│   │ rl │ 00 │"
65///     "│   │ d  │    │"
66///     "└───┴────┴────┘"
67/// );
68/// ```
69#[derive(Debug, Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
70pub struct Priority;
71
72impl Priority {
73    /// Returns a [`Peaker`] which goes over list one by one,
74    /// in order from left to right with no prioritization,
75    /// just peaking each value after another.
76    ///
77    /// ```
78    /// use tabled::{
79    ///     Table,
80    ///     settings::{Style, peaker::Priority, Width},
81    ///     assert::assert_table,
82    /// };
83    ///
84    /// let data = [
85    ///     ("1", "Hello", 100),
86    ///     ("2", "World", 1000),
87    /// ];
88    ///
89    /// let mut table = Table::new(data);
90    /// table.with(Style::modern());
91    /// table.with(Width::wrap(15).priority(Priority::none()));
92    ///
93    /// let output = table.to_string();
94    ///
95    /// assert_table!(
96    ///     output,
97    ///     "┌───┬────┬────┐"
98    ///     "│ & │ &s │ i3 │"
99    ///     "│ s │ tr │ 2  │"
100    ///     "│ t │    │    │"
101    ///     "│ r │    │    │"
102    ///     "├───┼────┼────┤"
103    ///     "│ 1 │ He │ 10 │"
104    ///     "│   │ ll │ 0  │"
105    ///     "│   │ o  │    │"
106    ///     "├───┼────┼────┤"
107    ///     "│ 2 │ Wo │ 10 │"
108    ///     "│   │ rl │ 00 │"
109    ///     "│   │ d  │    │"
110    ///     "└───┴────┴────┘"
111    /// );
112    /// ```
113    pub fn none() -> PriorityNone {
114        PriorityNone::new()
115    }
116
117    /// Returns a [`Peaker`] which goes over list peacking a minimum value,
118    /// and prioritizing a chosen side when equal values are met.
119    ///
120    /// ```
121    /// use tabled::{
122    ///     Table,
123    ///     settings::{Style, peaker::Priority, Width},
124    ///     assert::assert_table,
125    /// };
126    ///
127    /// let data = [
128    ///     ("1", "Hello", 100),
129    ///     ("2", "World", 1000),
130    /// ];
131    ///
132    /// let mut table = Table::new(data);
133    /// table.with(Style::modern());
134    /// table.with(Width::wrap(15).priority(Priority::min(true)));
135    ///
136    /// let output = table.to_string();
137    ///
138    /// assert_table!(
139    ///     output,
140    ///     "┌──┬───────┬──┐"
141    ///     "│  │ &str  │  │"
142    ///     "├──┼───────┼──┤"
143    ///     "│  │ Hello │  │"
144    ///     "├──┼───────┼──┤"
145    ///     "│  │ World │  │"
146    ///     "└──┴───────┴──┘"
147    /// );
148    /// ```
149    pub fn min(right: bool) -> PriorityMin {
150        PriorityMin::new(right)
151    }
152
153    /// Returns a [`Peaker`] which goes over list peacking a maximum value,
154    /// and prioritizing a chosen side when equal values are met.
155    ///
156    /// ```
157    /// use tabled::{
158    ///     Table,
159    ///     settings::{Style, peaker::Priority, Width},
160    ///     assert::assert_table,
161    /// };
162    ///
163    /// let data = [
164    ///     ("1", "Hello", 100),
165    ///     ("2", "World", 1000),
166    /// ];
167    ///
168    /// let mut table = Table::new(data);
169    /// table.with(Style::modern());
170    /// table.with(Width::wrap(15).priority(Priority::max(true)));
171    ///
172    /// let output = table.to_string();
173    ///
174    /// assert_table!(
175    ///     output,
176    ///     "┌────┬────┬───┐"
177    ///     "│ &s │ &s │ i │"
178    ///     "│ tr │ tr │ 3 │"
179    ///     "│    │    │ 2 │"
180    ///     "├────┼────┼───┤"
181    ///     "│ 1  │ He │ 1 │"
182    ///     "│    │ ll │ 0 │"
183    ///     "│    │ o  │ 0 │"
184    ///     "├────┼────┼───┤"
185    ///     "│ 2  │ Wo │ 1 │"
186    ///     "│    │ rl │ 0 │"
187    ///     "│    │ d  │ 0 │"
188    ///     "│    │    │ 0 │"
189    ///     "└────┴────┴───┘"
190    /// );
191    /// ```
192    pub fn max(right: bool) -> PriorityMax {
193        PriorityMax::new(right)
194    }
195
196    /// Returns a [`Peaker`] which goes over list peacking a left most value as far as possible.
197    ///
198    /// ```
199    /// use tabled::{
200    ///     Table,
201    ///     settings::{Style, peaker::Priority, Width},
202    ///     assert::assert_table,
203    /// };
204    ///
205    /// let data = [
206    ///     ("1", "Hello", 100),
207    ///     ("2", "World", 1000),
208    /// ];
209    ///
210    /// let mut table = Table::new(data);
211    /// table.with(Style::modern());
212    /// table.with(Width::wrap(15).priority(Priority::left()));
213    ///
214    /// let output = table.to_string();
215    ///
216    /// assert_table!(
217    ///     output,
218    ///     "┌──┬───┬──────┐"
219    ///     "│  │ & │ i32  │"
220    ///     "│  │ s │      │"
221    ///     "│  │ t │      │"
222    ///     "│  │ r │      │"
223    ///     "├──┼───┼──────┤"
224    ///     "│  │ H │ 100  │"
225    ///     "│  │ e │      │"
226    ///     "│  │ l │      │"
227    ///     "│  │ l │      │"
228    ///     "│  │ o │      │"
229    ///     "├──┼───┼──────┤"
230    ///     "│  │ W │ 1000 │"
231    ///     "│  │ o │      │"
232    ///     "│  │ r │      │"
233    ///     "│  │ l │      │"
234    ///     "│  │ d │      │"
235    ///     "└──┴───┴──────┘"
236    /// );
237    /// ```
238    pub fn left() -> PriorityLeft {
239        PriorityLeft::new()
240    }
241
242    /// Returns a [`Peaker`] which goes over list peacking a right most value as far as possible.
243    ///
244    /// ```
245    /// use tabled::{
246    ///     Table,
247    ///     settings::{Style, peaker::Priority, Width},
248    ///     assert::assert_table,
249    /// };
250    ///
251    /// let data = [
252    ///     ("1", "Hello", 100),
253    ///     ("2", "World", 1000),
254    /// ];
255    ///
256    /// let mut table = Table::new(data);
257    /// table.with(Style::modern());
258    /// table.with(Width::wrap(15).priority(Priority::right()));
259    ///
260    /// let output = table.to_string();
261    ///
262    /// assert_table!(
263    ///     output,
264    ///     "┌──────┬───┬──┐"
265    ///     "│ &str │ & │  │"
266    ///     "│      │ s │  │"
267    ///     "│      │ t │  │"
268    ///     "│      │ r │  │"
269    ///     "├──────┼───┼──┤"
270    ///     "│ 1    │ H │  │"
271    ///     "│      │ e │  │"
272    ///     "│      │ l │  │"
273    ///     "│      │ l │  │"
274    ///     "│      │ o │  │"
275    ///     "├──────┼───┼──┤"
276    ///     "│ 2    │ W │  │"
277    ///     "│      │ o │  │"
278    ///     "│      │ r │  │"
279    ///     "│      │ l │  │"
280    ///     "│      │ d │  │"
281    ///     "└──────┴───┴──┘"
282    /// );
283    /// ```
284    pub fn right() -> PriorityRight {
285        PriorityRight::new()
286    }
287}