dysk_cli/
sorting.rs

1use {
2    crate::{
3        col::Col,
4        order::Order,
5    },
6    lfs_core::Mount,
7    std::{
8        error,
9        fmt,
10        str::FromStr,
11    },
12};
13
14/// Sorting directive: the column and the order (asc or desc)
15#[derive(Debug, Clone, Copy, PartialEq)]
16pub struct Sorting {
17    col: Col,
18    order: Order,
19}
20
21impl Default for Sorting {
22    fn default() -> Self {
23        let col = Col::default_sort_col();
24        let order = col.default_sort_order();
25        Self { col, order }
26    }
27}
28
29impl Sorting {
30    pub fn sort(self, mounts: &mut [Mount]) {
31        let comparator = self.col.comparator();
32        mounts.sort_by(comparator);
33        if self.order == Order::Desc {
34            mounts.reverse();
35        }
36    }
37}
38
39#[derive(Debug)]
40pub struct ParseSortingError {
41    raw: String,
42    reason: String,
43}
44impl ParseSortingError {
45    pub fn new<S: Into<String>, E: ToString>(raw: S, reason: E) -> Self {
46        Self {
47            raw: raw.into(),
48            reason: reason.to_string(),
49        }
50    }
51}
52impl fmt::Display for ParseSortingError {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        write!(f, "{:?} can't be parsed as a sort expression because {}", self.raw, self.reason)
55    }
56}
57impl error::Error for ParseSortingError {}
58
59impl FromStr for Sorting {
60    type Err = ParseSortingError;
61    fn from_str(s: &str) -> Result<Self, ParseSortingError> {
62        let cut_idx_len = s
63            .char_indices()
64            .find(|(_idx, c)| c.is_whitespace() || *c == '-')
65            .map(|(idx, c)| (idx, c.len_utf8()));
66        let (s_col, s_order) = match cut_idx_len {
67            Some((idx, len)) => (&s[..idx], Some(&s[idx+len..])),
68            None => (s, None),
69        };
70        let col: Col = s_col.parse()
71            .map_err(|pce| ParseSortingError::new(s, Box::new(pce)))?;
72        let order = match s_order {
73            Some(s_order) => {
74                s_order.parse()
75                    .map_err(|poe| ParseSortingError::new(s, Box::new(poe)))?
76            }
77            None => {
78                col.default_sort_order()
79            }
80        };
81        Ok(Self { col, order })
82    }
83}