tabled/features/
peaker.rs

1//! The module contains [`Peaker`] trait and its implementations to be used in [`Height`] and [`Width`].
2//!
3//! [`Width`]: crate::Width
4//! [`Height`]: crate::Height
5
6/// A strategy of width function.
7/// It determines the order how the function is applied.
8pub trait Peaker {
9    /// Creates a new instance.
10    fn create() -> Self;
11    /// This function returns a column index which will be changed.
12    /// Or `None` if no changes are necessary.
13    fn peak(&mut self, min_widths: &[usize], widths: &[usize]) -> Option<usize>;
14}
15
16/// A Peaker which goes over column 1 by 1.
17#[derive(Debug, Default, Clone)]
18pub struct PriorityNone {
19    i: usize,
20}
21
22impl Peaker for PriorityNone {
23    fn create() -> Self {
24        Self { i: 0 }
25    }
26
27    fn peak(&mut self, _: &[usize], widths: &[usize]) -> Option<usize> {
28        let mut i = self.i;
29        let mut count_empty = 0;
30        while widths[i] == 0 {
31            i += 1;
32            if i >= widths.len() {
33                i = 0;
34            }
35
36            count_empty += 1;
37            if count_empty == widths.len() {
38                return None;
39            }
40        }
41
42        let col = i;
43
44        i += 1;
45        if i >= widths.len() {
46            i = 0;
47        }
48
49        self.i = i;
50
51        Some(col)
52    }
53}
54
55/// A Peaker which goes over the biggest column first.
56#[derive(Debug, Default, Clone)]
57pub struct PriorityMax;
58
59impl Peaker for PriorityMax {
60    fn create() -> Self {
61        Self
62    }
63
64    fn peak(&mut self, _: &[usize], widths: &[usize]) -> Option<usize> {
65        let col = (0..widths.len()).max_by_key(|&i| widths[i]).unwrap();
66        if widths[col] == 0 {
67            None
68        } else {
69            Some(col)
70        }
71    }
72}
73
74/// A Peaker which goes over the smallest column first.
75#[derive(Debug, Default, Clone)]
76pub struct PriorityMin;
77
78impl Peaker for PriorityMin {
79    fn create() -> Self {
80        Self
81    }
82
83    fn peak(&mut self, min_widths: &[usize], widths: &[usize]) -> Option<usize> {
84        let col = (0..widths.len())
85            .filter(|&i| min_widths.is_empty() || widths[i] > min_widths[i])
86            .min_by_key(|&i| widths[i])
87            .unwrap();
88        if widths[col] == 0 {
89            None
90        } else {
91            Some(col)
92        }
93    }
94}